home *** CD-ROM | disk | FTP | other *** search
- {
-
- This is Monster, a multiuser adventure game system
- where the players create the universe.
-
- Written by Rich Skrenta at Northwestern University, 1988.
-
- skrenta@nuacc.acns.nwu.edu
- skrenta@nuacc.bitnet
-
- }
-
- program monster(input,output);
-
- const
-
- %include 'privusers.pas'
-
- veryshortlen = 12; { very short string length for userid's etc }
- shortlen = 20; { ordinary short string }
-
- maxobjs = 15; { max objects allow on floor in a room }
- maxpeople = 10; { max people allowed in a room }
- maxplayers = 300; { max log entries to make for players }
- maxcmds = 75; { top value for cmd keyword slots }
- maxshow = 50; { top value for set/show keywords }
- maxexit = 6; { 6 exits from each loc: NSEWUD }
- maxroom = 1000; { Total maximum ever possible }
- maxdetail = 5; { max num of detail keys/descriptions per room }
- maxevent = 15; { event slots per event block }
- maxindex = 10000; { top value for bitmap allocation }
- maxhold = 6; { max # of things a player can be holding }
- maxerr = 15; { # of consecutive record collisions before the
- the deadlock error message is printed }
- numevnts = 10; { # of different event records to be maintained }
- numpunches = 12; { # of different kinds of punches there are }
- maxparm = 20; { parms for object USEs }
- maxspells = 50; { total number of spells available }
-
- descmax = 10; { lines per description block }
-
-
- DEFAULT_LINE = 32000; { A virtual one liner record number that
- really means "use the default one liner
- description instead of reading one from
- the file" }
-
- { Mnemonics for directions }
-
- north = 1;
- south = 2;
- east = 3;
- west = 4;
- up = 5;
- down = 6;
-
-
- { Index record mnemonics }
-
- I_BLOCK = 1; { True if description block is not used }
- I_LINE = 2; { True if line slot is not used }
- I_ROOM = 3; { True if room slot is not in use }
- I_PLAYER = 4; { True if slot is not occupied by a player }
- I_ASLEEP = 5; { True if player is not playing }
- I_OBJECT = 6; { True if object record is not being used }
- I_INT = 7; { True if int record is not being used }
-
- { Integer record mnemonics }
-
- N_LOCATION = 1; { Player's location }
- N_NUMROOMS = 2; { How many rooms they've made }
- N_ALLOW = 3; { How many rooms they're allowed to make }
- N_ACCEPT = 4; { Number of open accept exits they have }
- N_EXPERIENCE = 5; { How "good" they are }
- N_SELF = 6; { player's self descriptions }
-
- { object kind mnemonics }
-
- O_BLAND = 0; { bland object, good for keys }
- O_WEAPON = 1;
- O_ARMOR = 2;
- O_THRUSTER = 3; { use puts player through an exit }
- O_CLOAK = 4;
-
- O_BAG = 100;
- O_CRYSTAL = 101;
- O_WAND = 102;
- O_HAND = 103;
-
-
- { Command Mnemonics }
- error = 0;
- setnam = 1;
- help = 2;
- quest = 3;
- quit = 4;
- look = 5;
- go = 6;
- form = 7;
- link = 8;
- unlink = 9;
- c_whisper = 10;
- poof = 11;
- desc = 12;
- dbg = 14;
- say = 15;
-
- c_rooms = 17;
- c_system = 18;
- c_disown = 19;
- c_claim = 20;
- c_create = 21;
- c_public = 22;
- c_accept = 23;
- c_refuse = 24;
- c_zap = 25;
- c_hide = 26;
- c_l = 27;
- c_north = 28;
- c_south = 29;
- c_east = 30;
- c_west = 31;
- c_up = 32;
- c_down = 33;
- c_n = 34;
- c_s = 35;
- c_e = 36;
- c_w = 37;
- c_u = 38;
- c_d = 39;
- c_custom = 40;
- c_who = 41;
- c_players = 42;
- c_search = 43;
- c_unhide = 44;
- c_punch = 45;
- c_ping = 46;
- c_health = 47;
- c_get = 48;
- c_drop = 49;
- c_inv = 50;
- c_i = 51;
- c_self = 52;
- c_whois = 53;
- c_duplicate = 54;
-
- c_version = 56;
- c_objects = 57;
- c_use = 58;
- c_wield = 59;
- c_brief = 60;
- c_wear = 61;
- c_relink = 62;
- c_unmake = 63;
- c_destroy = 64;
- c_show = 65;
- c_set = 66;
-
- e_detail = 100; { pseudo command for log_action of desc exit }
- e_custroom = 101; { customizing this room }
- e_program = 102; { customizing (programming) an object }
- e_usecrystal = 103; { using a crystal ball }
-
-
- { Show Mnemonics }
-
- s_exits = 1;
- s_object = 2;
- s_quest = 3;
- s_details = 4;
-
-
- { Set Mnemonics }
-
- y_quest = 1;
- y_altmsg = 2;
- y_group1 = 3;
- y_group2 = 4;
-
-
- { Event Mnemonics }
-
- E_EXIT = 1; { player left room }
- E_ENTER = 2; { player entered room }
- E_BEGIN = 3; { player joined game here }
- E_QUIT = 4; { player here quit game }
-
- E_SAY = 5; { someone said something }
- E_SETNAM = 6; { player set his personal name }
- E_POOFIN = 8; { someone poofed into this room }
- E_POOFOUT = 9; { someone poofed out of this room }
- E_DETACH = 10; { a link has been destroyed }
- E_EDITDONE = 11; { someone is finished editing a desc }
- E_NEWEXIT = 12; { someone made an exit here }
- E_BOUNCEDIN = 13; { an object "bounced" into the room }
- E_EXAMINE = 14; { someone is examining something }
- E_CUSTDONE = 15; { someone is done customizing an exit }
- E_FOUND = 16; { player found something }
- E_SEARCH = 17; { player is searching room }
- E_DONEDET = 18; { done adding details to a room }
- E_HIDOBJ = 19; { someone hid an object here }
- E_UNHIDE = 20; { voluntarily revealed themself }
- E_FOUNDYOU = 21; { someone found someone else hiding }
- E_PUNCH = 22; { someone has punched someone else }
- E_MADEOBJ = 23; { someone made an object here }
- E_GET = 24; { someone picked up an object }
- E_DROP = 25; { someone dropped an object }
- E_DROPALL = 26; { quit & dropped stuff on way out }
- E_IHID = 27; { tell others that I have hidden (!) }
- E_NOISES = 28; { strange noises from hidden people }
- E_PING = 29; { send a ping to a potential zombie }
- E_PONG = 30; { ping answered }
- E_HIDEPUNCH = 31; { someone hidden is attacking }
- E_SLIPPED = 32; { attack caused obj to drop unwillingly }
- E_ROOMDONE = 33; { done customizing this room }
- E_OBJDONE = 34; { done programming an object }
- E_HPOOFOUT = 35; { someone hiding poofed out }
- E_FAILGO = 36; { a player failed to go through an exit }
- E_HPOOFIN = 37; { someone poofed into a room hidden }
- E_TRYPUNCH = 38; { someone failed to punch someone else }
- E_PINGONE = 39; { someone was pinged away . . . }
- E_CLAIM = 40; { someone claimed this room }
- E_DISOWN = 41; { owner of this room has disowned it }
- E_WEAKER = 42; { person is weaker from battle }
- E_OBJCLAIM = 43; { someone claimed an object }
- E_OBJDISOWN = 44; { someone disowned an object }
- E_SELFDONE = 45; { done editing self description }
- E_WHISPER = 46; { someone whispers to someone else }
- E_WIELD = 47; { player wields a weapon }
- E_UNWIELD = 48; { player puts a weapon away }
- E_DONECRYSTALUSE = 49; { done using the crystal ball }
- E_WEAR = 50; { someone has put on something }
- E_UNWEAR = 51; { someone has taken off something }
- E_DESTROY = 52; { someone has destroyed an object }
- E_HIDESAY = 53; { anonymous say }
- E_OBJPUBLIC = 54; { someone made an object public }
- E_SYSDONE = 55; { done with system maint. mode }
- E_UNMAKE = 56; { remove typedef for object }
- E_LOOKDETAIL = 57; { looking at a detail of this room }
- E_ACCEPT = 58; { made an "accept" exit here }
- E_REFUSE = 59; { got rid of an "accept" exit here }
- E_DIED = 60; { someone died and evaporated }
- E_LOOKYOU = 61; { someone is looking at you }
- E_FAILGET = 62; { someone can't get something }
- E_FAILUSE = 63; { someone can't use something }
- E_CHILL = 64; { someone scrys you }
- E_NOISE2 = 65; { say while in crystal ball }
- E_LOOKSELF = 66; { someone looks at themself }
- E_INVENT = 67; { someone takes inventory }
- E_POOFYOU = 68; { MM poofs someone away . . . . }
- E_WHO = 69; { someone does a who }
- E_PLAYERS = 70; { someone does a players }
- E_VIEWSELF = 71; { someone views a self description }
- E_REALNOISE = 72; { make the real noises message print }
- E_ALTNOISE = 73; { alternate mystery message }
- E_MIDNIGHT = 74; { it's midnight now, tell everyone }
-
- E_ACTION = 100; { base command action event }
-
-
- { Misc. }
-
- GOODHEALTH = 7;
-
-
- type
- string = varying[80] of char;
- veryshortstring = varying[veryshortlen] of char;
- shortstring = varying[shortlen] of char;
-
- { This is a list of description block numbers;
- If a number is zero, there is no text for that block }
-
-
- { exit kinds:
- 0: no way - blocked exit
- 1: open passageway
- 2: object required
-
- 6: exit only exists if player is holding the key
- }
-
- exit = record
- toloc: integer; { location exit goes to }
- kind: integer; { type of the exit }
- slot: integer; { exit slot of toloc target }
-
- exitdesc, { one liner description of exit }
- closed, { desc of a closed door }
- fail, { description if can't go thru }
- success, { desc while going thru exit }
- goin, { what others see when you go into the exit }
- { ofail, }
- comeout: { what others see when you come out of the exit }
- integer; { all refer to the liner file }
- { if zero defaults will be printed }
-
- hidden: integer; { **** about to change this **** }
- objreq: integer; { object required to pass this exit }
-
- alias: veryshortstring; { alias for the exit dir, a keyword }
-
- reqverb: boolean; { require alias as a verb to work }
- reqalias: boolean; { require alias only (no direction) to
- pass through the exit }
- autolook: boolean; { do a look when user comes out of exit }
- end;
-
-
- { index record # 1 is block index }
- { index record # 2 is line index }
- { index record # 3 is room index }
- { index record # 4 is player alloc index }
- { index record # 5 is player awake (in game) index }
- indexrec = record
- indexnum: integer; { validation number }
- free: packed array[1..maxindex] of boolean;
- top: integer; { max records available }
- inuse: integer; { record #s in use }
- end;
-
-
- { names are record #1 }
- { owners are record # 2 }
- { player pers_names are record # 3 }
- { userids are record # 4 }
- { object names are record # 5 }
- { object creators are record # 6 }
- { date of last play is # 7 }
- { time of last play is # 8 }
- namrec = record
- validate: integer;
- loctop: integer;
- idents: array[1..maxroom] of shortstring;
- end;
-
- objectrec = record
- objnum: integer; { allocation number for the object }
- onum: integer; { number index to objnam/objown }
- oname: shortstring; { duplicate of name of object }
- kind: integer; { what kind of object this is }
- linedesc: integer; { liner desc of object Here }
-
- home: integer; { if object at home, then print the }
- homedesc: integer; { home description }
-
- actindx: integer; { action index -- programs for the future }
- examine: integer; { desc block for close inspection }
- worth: integer; { how much it cost to make (in gold) }
- numexist: integer; { number in existence }
-
- sticky: boolean; { can they ever get it? }
- getobjreq: integer; { object required to get this object }
- getfail: integer; { fail-to-get description }
- getsuccess: integer; { successful picked up description }
-
- useobjreq: integer; { object require to use this object }
- uselocreq: integer; { place have to be to use this object }
- usefail: integer; { fail-to-use description }
- usesuccess: integer; { successful use of object description }
-
- usealias: veryshortstring;
- reqalias: boolean;
- reqverb: boolean;
-
- particle: integer; { a,an,some, etc... "particle" is not
- be right, but hey, it's in the code }
-
- parms: array[1..maxparm] of integer;
-
- d1: integer; { extra description # 1 }
- d2: integer; { extra description # 2 }
- exp3,exp4,exp5,exp6: integer;
- end;
-
- anevent = record
- sender, { slot of sender }
- action, { what event this is, E_something }
- target, { opt target of action }
- parm: integer; { expansion parm }
- msg: string; { string for SAY and other cmds }
- loc: integer; { room that event is targeted for }
- end;
-
- eventrec = record
- validat: integer; { validation number for record locking }
- evnt: array[1..maxevent] of anevent;
- point: integer; { circular buffer pointer }
- end;
-
- peoplerec = record
- kind: integer; { 0=none,1=player,2=npc }
- parm: integer; { index to npc controller (object?) }
-
- username: veryshortstring; { actual userid of person }
- name: shortstring; { chosen name of person }
- hiding: integer; { degree to which they're hiding }
- act,targ: integer; { last thing that this person did }
-
- holding: array[1..maxhold] of integer; { objects being held }
- experience: integer;
-
- wearing: integer; { object that they're wearing }
- wielding: integer; { weapon they're wielding }
- health: integer; { how healthy they are }
-
- self: integer; { self description }
-
- ex1,ex2,ex3,ex4,ex5: integer;
- end;
-
- spellrec = record
- recnum: integer;
- level: array[1..maxspells] of integer;
- end;
-
- descrec = record
- descrinum: integer;
- lines: array[1..descmax] of string;
- desclen: integer; { number used in this block }
- end;
-
- linerec = record
- linenum: integer;
- theline: string;
- end;
-
- room = record
- valid: integer; { validation number for record locking }
- locnum: integer;
- owner: veryshortstring; { who owns the room: userid if private
- '' if public
- '*' if disowned }
- nicename: string; { pretty name for location }
- nameprint: integer; { code for printing name:
- 0: don't print it
- 1: You're in
- 2: You're at
- }
-
- primary: integer; { room descriptions }
- secondary: integer;
- which: integer; { 0 = only print primary room desc.
- 1 = only print secondary room desc.
- 2 = print both
- 3 = print primary then secondary
- if has magic object }
-
- magicobj: integer; { special object for this room }
- effects: integer;
- parm: integer;
-
- exits: array[1..maxexit] of exit;
-
- pile: integer; { if more than maxobjs objects here }
- objs: array[1..maxobjs] of integer; { refs to object file }
- objhide: array[1..maxobjs] of integer; { how much each object
- is hidden }
- { see hidden on exitrec
- above }
-
- objdrop: integer; { where objects go when they're dropped }
- objdesc: integer; { what it says when they're dropped }
- objdest: integer; { what it says in target room when
- "bounced" object comes in }
-
- people: array[1..maxpeople] of peoplerec;
-
- grploc1,grploc2: integer;
- grpnam1,grpnam2: shortstring;
-
- detail: array[1..maxdetail] of veryshortstring;
- detaildesc: array[1..maxdetail] of integer;
-
- trapto: integer; { where the "trapdoor" goes }
- trapchance: integer; { how often the trapdoor works }
-
- rndmsg: integer; { message that randomly prints }
-
- xmsg2: integer; { another random block }
- exp2,exp3,exp4: integer;
- exitfail: integer; { default fail description for exits }
- ofail: integer; { what other's see when you fail, default }
- end;
-
-
- intrec = record
- intnum: integer;
- int: array[1..maxplayers] of integer;
- end;
-
-
- var
- old_prompt: [external] string;
- line: [external] string;
- oldcmd: string; { string for '.' command to do last command }
-
- inmem: boolean; { Is this rooms roomrec (here....) in memory?
- We call gethere many times to make sure
- here is current. However, we only want to
- actually do a getroom if the roomrec has been
- modified }
- brief: boolean := FALSE; { brief/verbose descriptions }
-
- rndcycle: integer; { integer for rnd_event }
- debug: boolean;
- ping_answered: boolean; { flag for ping answers }
- hiding : boolean := FALSE; { is player hiding? }
- midnight_notyet: boolean := TRUE; { hasn't been midnight yet }
- first_puttoken: boolean := TRUE; { flag for first place into world }
- logged_act : boolean := FALSE; { flag to indicate that a log_action
- has been called, and the next call
- to clear_command needs to clear the
- action parms in the here roomrec }
-
- roomfile : file of room;
- eventfile: file of eventrec;
- namfile: file of namrec;
- descfile: file of descrec;
- linefile: file of linerec;
- indexfile: file of indexrec;
- intfile: file of intrec;
- objfile: file of objectrec;
- spellfile: file of spellrec;
-
- cmds: array[1..maxcmds] of shortstring := (
-
- 'name', { setnam = 1 }
- 'help', { help = 2 }
- '?', { quest = 3 }
- 'quit', { quit = 4 }
- 'look', { look = 5 }
- 'go', { go = 6 }
- 'form', { form = 7 }
- 'link', { link = 8 }
- 'unlink', { unlink = 9 }
- 'whisper', { c_whisper = 10}
- 'poof', { poof = 11 }
- 'describe', { desc = 12 }
- '',
- 'debug', { dbg = 14 }
- 'say', { say = 15 }
- '', { }
- 'rooms', { c_rooms = 17 }
- 'system', { c_system = 18 }
- 'disown', { c_disown = 19 }
- 'claim', { c_claim = 20 }
- 'make', { c_create = 21 }
- 'public', { c_public = 22 }
- 'accept', { c_accept = 23 }
- 'refuse', { c_refuse = 24 }
- 'zap', { c_zap = 25 }
- 'hide', { c_hide = 26 }
- 'l', { c_l = 27 }
- 'north', { c_north = 28 }
- 'south', { c_south = 29 }
- 'east', { c_east = 30 }
- 'west', { c_west = 31 }
- 'up', { c_up = 32 }
- 'down', { c_down = 33 }
- 'n', { c_n = 34 }
- 's', { c_s = 35 }
- 'e', { c_e = 36 }
- 'w', { c_w = 37 }
- 'u', { c_u = 38 }
- 'd', { c_d = 39 }
- 'customize', { c_custom = 40 }
- 'who', { c_who = 41 }
- 'players', { c_players = 42}
- 'search', { c_search = 43 }
- 'reveal', { c_unhide = 44 }
- 'punch', { c_punch = 45 }
- 'ping', { c_ping = 46 }
- 'health', { c_health = 47 }
- 'get', { c_get = 48 }
- 'drop', { c_drop = 49 }
- 'inventory', { c_inv = 50 }
- 'i', { c_i = 51 }
- 'self', { c_self = 52 }
- 'whois', { c_whois = 53 }
- 'duplicate', { c_duplicate = 54 }
- '',
- 'version', { c_version = 56}
- 'objects', { c_objects = 57}
- 'use', { c_use = 58 }
- 'wield', { c_wield = 59 }
- 'brief', { c_brief = 60 }
- 'wear', { c_wear = 61 }
- 'relink', { c_relink = 62 }
- 'unmake', { c_unmake = 63 }
- 'destroy', { c_destroy = 64}
- 'show', { c_show = 65 }
- 'set', { c_set = 66 }
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ''
- );
-
-
- numcmds: integer; { number of main level commands there are }
- show: array[1..maxshow] of shortstring;
- numshow: integer;
- setkey: array[1..maxshow] of shortstring;
- numset: integer;
-
- direct: array[1..maxexit] of shortstring :=
- ('north','south','east','west','up','down');
-
- spells: array[1..maxspells] of string; { names of spells }
- numspells: integer; { number of spells there actually are }
-
- done: boolean; { flag for QUIT }
- userid: veryshortstring; { userid of this player }
- location: integer; { current place number }
-
- hold_kind: array[1..maxhold] of integer; { kinds of the objects i'm
- holding }
-
- myslot: integer := 1; { here.people[myslot]... is this player }
- myname: shortstring; { personal name this player chose (setname) }
- myevent: integer; { which point in event buffer we are at }
-
- found_exit: array[1..maxexit] of boolean;
- { has exit i been found by the player? }
-
- mylog: integer; { which log entry this player is }
- mywear: integer; { what I'm wearing }
- mywield: integer; { weapon I'm wielding }
- myhealth: integer; { how well I'm feeling }
- myexperience: integer; { how experienced I am }
- myself: integer; { self description block }
-
- healthcycle: integer; { used in rnd_event to control how quickly a
- player heals }
-
- here: room; { current room record }
- event: eventrec;
- privd: boolean;
-
- objnam, { object names }
- objown, { object owners }
- nam, { record 1 is room names }
- own, { rec 2 is room owners }
- pers, { 3 is player personal names }
- user, { 4 is player userid }
- adate, { 5 is date of last play }
- atime { 6 is time of last play }
- : namrec;
-
- anint: intrec; { info about game players }
- obj: objectrec;
- spell: spellrec;
-
- block: descrec; { a text block of descmax lines }
- indx: indexrec; { an record allocation record }
- oneliner: linerec; { a line record }
-
- heredsc: descrec;
-
-
- [external]
- procedure wait(seconds: real); { system SLEEP call }
- external;
-
- [external]
- function random:real; { system random number generator }
- external;
-
- [external]
- function rnd100: integer; { returns a random # between 0-100 }
- external;
-
- [external]
- procedure setup_guts; { disables ctrl-Y/ctrl-C }
- { necessary to prevent ZOMBIES in the world }
- extern;
-
- [external]
- procedure finish_guts; { re-enables ctrl-Y/ctrl-C }
- extern;
-
- [external] function get_userid:string;
- external;
-
- [external] function trim(s: string): string;
- external;
-
- [external]
- procedure grab_line(prompt: string; var s:string; echo:boolean := true);
- { Input routine. Gets a line of text from user which checking
- for async events }
- external;
-
- [external]
- procedure putchars(s: string);
- extern;
-
- procedure xpoof(loc: integer);
- forward;
-
- procedure do_exit(exit_slot: integer);
- forward;
-
- function put_token(room: integer;var aslot:integer;hidelev:integer := 0):boolean;
- forward;
-
- procedure take_token(aslot, roomno: integer);
- forward;
-
- procedure maybe_drop;
- forward;
-
- procedure do_program(objnam: string);
- forward;
-
- function drop_everything(pslot: integer := 0): boolean;
- forward;
-
-
- procedure collision_wait;
- var
- wait_time: real;
-
- begin
- wait_time := random;
- if wait_time < 0.001 then
- wait_time := 0.001;
- wait(wait_time);
- end;
-
-
- { increment err; if err is too high, suspect deadlock }
- { this is called by all getX procedures to ease deadlock checking }
- procedure deadcheck(var err: integer; s:string);
-
- begin
- err := err + 1;
- if err > maxerr then begin
- writeln('%warning- ',s,' seems to be deadlocked; notify the Monster Manager');
- finish_guts;
- halt;
- err := 0;
- end;
- end;
-
-
-
- { first procedure of form getX
- attempts to get given room record
- resolves record access conflicts, checks for deadlocks
- Locks record; use freeroom immediately after getroom if data is
- for read-only
- }
- procedure getroom(n: integer:= 0);
- var
- err: integer;
-
- begin
- if n = 0 then
- n := location;
- roomfile^.valid := 0;
- err := 0;
- if debug then
- writeln('%getroom(',n:1,')');
- find(roomfile,n,error := continue);
- while roomfile^.valid <> n do begin
- deadcheck(err,'getroom');
- collision_wait;
- find(roomfile,n,error := continue);
- end;
- here := roomfile^;
-
- inmem := false;
- { since this getroom could be doing anything, we will
- assume that it is bozoing the correct here record for
- this room. If this getroom called by gethere, then
- gethere will correct inmem immediately. Otherwise
- the next gethere will restore the correct here record. }
- end;
-
- procedure putroom;
-
- begin
- locate(roomfile,here.valid);
- roomfile^ := here;
- put(roomfile);
- end;
-
- procedure freeroom; { unlock the record if you're not going to write it }
-
- begin
- unlock(roomfile);
- end;
-
- procedure gethere(n: integer := 0);
-
- begin
- if (n = 0) or (n = location) then begin
- if not(inmem) then begin
- getroom; { getroom(n) okay here also }
- freeroom;
- inmem := true;
- end else if debug then
- writeln('%gethere - here already in memory');
- end else begin
- getroom(n);
- freeroom;
- end;
- end;
-
-
- procedure getown;
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,2,error := continue);
- while namfile^.validate <> 2 do begin
- deadcheck(err,'getown');
- collision_wait;
- find(namfile,2,error := continue);
- end;
- own := namfile^;
- end;
-
-
-
- procedure getnam;
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,1,error := continue);
- while namfile^.validate <> 1 do begin
- deadcheck(err,'getnam');
- collision_wait;
- find(namfile,1,error := continue);
- end;
- nam := namfile^;
- end;
-
- procedure freenam;
-
- begin
- unlock(namfile);
- end;
-
- procedure freeown;
-
- begin
- unlock(namfile);
- end;
-
- procedure putnam;
-
- begin
- locate(namfile,1);
- namfile^:= nam;
- put(namfile);
- end;
-
- procedure putown;
-
- begin
- locate(namfile,2);
- namfile^:= own;
- put(namfile);
- end;
-
-
- procedure getobj(n: integer);
- var
- err: integer;
-
- begin
- if n = 0 then
- n := location;
- objfile^.objnum := 0;
- err := 0;
- find(objfile,n,error := continue);
- while objfile^.objnum <> n do begin
- deadcheck(err,'getobj');
- collision_wait;
- find(objfile,n,error := continue);
- end;
- obj := objfile^;
- end;
-
- procedure putobj;
-
- begin
- locate(objfile,obj.objnum);
- objfile^ := obj;
- put(objfile);
- end;
-
- procedure freeobj; { unlock the record if you're not going to write it }
-
- begin
- unlock(objfile);
- end;
-
-
-
- procedure getint(n: integer);
- var
- err: integer;
-
- begin
- intfile^.intnum := 0;
- err := 0;
- find(intfile,n,error := continue);
- while intfile^.intnum <> n do begin
- deadcheck(err,'getint');
- collision_wait;
- find(intfile,n,error := continue);
- end;
- anint := intfile^;
- end;
-
-
- procedure freeint;
-
- begin
- unlock(intfile);
- end;
-
- procedure putint;
- var
- n: integer;
-
- begin
- n := anint.intnum;
- locate(intfile,n);
- intfile^:= anint;
- put(intfile);
- end;
-
-
-
- procedure getspell(n: integer := 0);
- var
- err: integer;
-
- begin
- if n = 0 then
- n := mylog;
-
- spellfile^.recnum := 0;
- err := 0;
- find(spellfile,n,error := continue);
- while spellfile^.recnum <> n do begin
- deadcheck(err,'getspell');
- collision_wait;
- find(spellfile,n,error := continue);
- end;
- spell := spellfile^;
- end;
-
-
- procedure freespell;
-
- begin
- unlock(spellfile);
- end;
-
- procedure putspell;
- var
- n: integer;
-
- begin
- n := spell.recnum;
- locate(spellfile,n);
- spellfile^:= spell;
- put(spellfile);
- end;
-
-
-
- procedure getuser; { get log rec with everyone's userids in it }
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,4,error := continue);
- while namfile^.validate <> 4 do begin
- deadcheck(err,'getuser');
- collision_wait;
- find(namfile,4,error := continue);
- end;
- user := namfile^;
- end;
-
- procedure freeuser;
-
- begin
- unlock(namfile);
- end;
-
- procedure putuser;
-
- begin
- locate(namfile,4);
- namfile^:= user;
- put(namfile);
- end;
-
-
-
- procedure getdate; { get log rec with date of last play in it }
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,7,error := continue);
- while namfile^.validate <> 7 do begin
- deadcheck(err,'getdate');
- collision_wait;
- find(namfile,7,error := continue);
- end;
- adate := namfile^;
- end;
-
- procedure freedate;
-
- begin
- unlock(namfile);
- end;
-
- procedure putdate;
-
- begin
- locate(namfile,7);
- namfile^:= adate;
- put(namfile);
- end;
-
-
- procedure gettime; { get log rec with time of last play in it }
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,8,error := continue);
- while namfile^.validate <> 8 do begin
- deadcheck(err,'gettime');
- collision_wait;
- find(namfile,8,error := continue);
- end;
- atime := namfile^;
- end;
-
- procedure freetime;
-
- begin
- unlock(namfile);
- end;
-
- procedure puttime;
-
- begin
- locate(namfile,8);
- namfile^:= atime;
- put(namfile);
- end;
-
-
-
- procedure getobjnam;
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,5,error := continue);
- while namfile^.validate <> 5 do begin
- deadcheck(err,'getobjnam');
- collision_wait;
- find(namfile,5,error := continue);
- end;
- objnam := namfile^;
- end;
-
- procedure freeobjnam;
-
- begin
- unlock(namfile);
- end;
-
- procedure putobjnam;
-
- begin
- locate(namfile,5);
- namfile^:= objnam;
- put(namfile);
- end;
-
-
-
- procedure getobjown;
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,6,error := continue);
- while namfile^.validate <> 6 do begin
- deadcheck(err,'getobjown');
- collision_wait;
- find(namfile,6,error := continue);
- end;
- objown := namfile^;
- end;
-
- procedure freeobjown;
-
- begin
- unlock(namfile);
- end;
-
- procedure putobjown;
-
- begin
- locate(namfile,6);
- namfile^:= objown;
- put(namfile);
- end;
-
-
-
- procedure getpers; { get log rec with everyone's pers names in it }
- var
- err: integer;
-
- begin
- namfile^.validate := 0;
- err := 0;
- find(namfile,3,error := continue);
- while namfile^.validate <> 3 do begin
- deadcheck(err,'getpers');
- collision_wait;
- find(namfile,3,error := continue);
- end;
- pers := namfile^;
- end;
-
- procedure freepers;
-
- begin
- unlock(namfile);
- end;
-
- procedure putpers;
-
- begin
- locate(namfile,3);
- namfile^:= pers;
- put(namfile);
- end;
-
-
-
-
- procedure getevent(n: integer := 0);
- var
- err: integer;
-
- begin
- if n = 0 then
- n := location;
-
- n := (n mod numevnts) + 1;
-
- eventfile^.validat := 0;
- err := 0;
- find(eventfile,n,error := continue);
- while eventfile^.validat <> n do begin
- deadcheck(err,'getevent');
- collision_wait;
- find(eventfile,n,error := continue);
- end;
- event := eventfile^;
- end;
-
- procedure freeevent;
-
- begin
- unlock(eventfile);
- end;
-
- procedure putevent;
-
- begin
- locate(eventfile,event.validat);
- eventfile^:= event;
- put(eventfile);
- end;
-
-
- procedure getblock(n: integer);
- var
- err: integer;
-
- begin
- if debug then
- writeln('%getblock: ',n:1);
- descfile^.descrinum := 0;
- err := 0;
- find(descfile,n,error := continue);
- while descfile^.descrinum <> n do begin
- deadcheck(err,'getblock');
- collision_wait;
- find(descfile,n,error := continue);
- end;
- block := descfile^;
- end;
-
- procedure putblock;
- var
- n: integer;
-
- begin
- n := block.descrinum;
- if debug then
- writeln('%putblock: ',n:1);
- if n <> 0 then begin
- locate(descfile,n);
- descfile^ := block;
- put(descfile);
- end;
- end;
-
- procedure freeblock; { unlock the record if you're not going to write it }
-
- begin
- unlock(descfile);
- end;
-
-
-
-
-
- { *** new code begins here *** }
-
-
- procedure getline(n: integer);
- var
- err: integer;
-
- begin
- if n = -1 then begin
- oneliner.theline := '';
- end else begin
- err := 0;
- linefile^.linenum := 0;
- find(linefile,n,error := continue);
- while linefile^.linenum <> n do begin
- deadcheck(err,'getline');
- collision_wait;
- find(linefile,n,error := continue);
- end;
- oneliner := linefile^;
- end;
- end;
-
- procedure putline;
-
- begin
- if oneliner.linenum > 0 then begin
- locate(linefile,oneliner.linenum);
- linefile^ := oneliner;
- put(linefile);
- end;
- end;
-
- procedure freeline; { unlock the record if you're not going to write it }
-
- begin
- unlock(linefile);
- end;
-
-
-
-
- {
- Index record 1 -- Description blocks that are free
- Index record 2 -- One liners that are free
- }
-
-
- procedure getindex(n: integer);
- var
- err: integer;
-
- begin
- indexfile^.indexnum := 0;
- err := 0;
- find(indexfile,n,error := continue);
- while indexfile^.indexnum <> n do begin
- deadcheck(err,'getindex');
- collision_wait;
- find(indexfile,n,error := continue);
- end;
- indx := indexfile^;
- end;
-
- procedure putindex;
-
- begin
- locate(indexfile,indx.indexnum);
- indexfile^ := indx;
- put(indexfile);
- end;
-
- procedure freeindex; { unlock the record if you're not going to write it }
-
- begin
- unlock(indexfile);
- end;
-
-
-
- {
- First procedure of form alloc_X
- Allocates the oneliner resource using the indexrec bitmaps
-
- Return the number of a one liner if one is available
- and remove it from the free list
- }
- function alloc_line(var n: integer):boolean;
- var
- found: boolean;
-
- begin
- getindex(I_LINE);
- if indx.inuse = indx.top then begin
- freeindex;
- n := 0;
- alloc_line := false;
- writeln('There are no available one line descriptions.');
- end else begin
- n := 1;
- found := false;
- while (not found) and (n <= indx.top) do begin
- if indx.free[n] then
- found := true
- else
- n := n + 1;
- end;
- if found then begin
- indx.free[n] := false;
- alloc_line := true;
- indx.inuse := indx.inuse + 1;
- putindex;
- end else begin
- freeindex;
- writeln('%serious error in alloc_line; notify Monster Manager');
-
- alloc_line := false;
- end;
- end;
- end;
-
- {
- put the line specified by n back on the free list
- zeroes n also, for convenience
- }
- procedure delete_line(var n: integer);
-
- begin
- if n = DEFAULT_LINE then
- n := 0
- else if n > 0 then begin
- getindex(I_LINE);
- indx.inuse := indx.inuse - 1;
- indx.free[n] := true;
- putindex;
- end;
- n := 0;
- end;
-
-
-
- function alloc_int(var n: integer):boolean;
- var
- found: boolean;
-
- begin
- getindex(I_INT);
- if indx.inuse = indx.top then begin
- freeindex;
- n := 0;
- alloc_int := false;
- writeln('There are no available integer records.');
- end else begin
- n := 1;
- found := false;
- while (not found) and (n <= indx.top) do begin
- if indx.free[n] then
- found := true
- else
- n := n + 1;
- end;
- if found then begin
- indx.free[n] := false;
- alloc_int := true;
- indx.inuse := indx.inuse + 1;
- putindex;
- end else begin
- freeindex;
- writeln('%serious error in alloc_int; notify Monster Manager');
-
- alloc_int := false;
- end;
- end;
- end;
-
-
- procedure delete_int(var n: integer);
-
- begin
- if n > 0 then begin
- getindex(I_INT);
- indx.inuse := indx.inuse - 1;
- indx.free[n] := true;
- putindex;
- end;
- n := 0;
- end;
-
-
-
- {
- Return the number of a description block if available and
- remove it from the free list
- }
- function alloc_block(var n: integer):boolean;
- var
- found: boolean;
-
- begin
- if debug then
- writeln('%alloc_block entry');
- getindex(I_BLOCK);
- if indx.inuse = indx.top then begin
- freeindex;
- n := 0;
- alloc_block := false;
- writeln('There are no available description blocks.');
- end else begin
- n := 1;
- found := false;
- while (not found) and (n <= indx.top) do begin
- if indx.free[n] then
- found := true
- else
- n := n + 1;
- end;
- if found then begin
- indx.free[n] := false;
- alloc_block := true;
- indx.inuse := indx.inuse + 1;
- putindex;
- if debug then
- writeln('%alloc_block successful');
- end else begin
- freeindex;
- writeln('%serious error in alloc_block; notify Monster Manager');
- alloc_block := false;
- end;
- end;
- end;
-
-
-
-
- {
- puts a description block back on the free list
- zeroes n for convenience
- }
- procedure delete_block(var n: integer);
-
- begin
- if n = DEFAULT_LINE then
- n := 0 { no line really exists in the file }
- else if n > 0 then begin
- getindex(I_BLOCK);
- indx.inuse := indx.inuse - 1;
- indx.free[n] := true;
- putindex;
- n := 0;
- end else if n < 0 then begin
- n := (- n);
- delete_line(n);
- end;
- end;
-
-
-
- {
- Return the number of a room if one is available
- and remove it from the free list
- }
- function alloc_room(var n: integer):boolean;
- var
- found: boolean;
-
- begin
- getindex(I_ROOM);
- if indx.inuse = indx.top then begin
- freeindex;
- n := 0;
- alloc_room := false;
- writeln('There are no available free rooms.');
- end else begin
- n := 1;
- found := false;
- while (not found) and (n <= indx.top) do begin
- if indx.free[n] then
- found := true
- else
- n := n + 1;
- end;
- if found then begin
- indx.free[n] := false;
- alloc_room := true;
- indx.inuse := indx.inuse + 1;
- putindex;
- end else begin
- freeindex;
- writeln('%serious error in alloc_room; notify Monster Manager');
- alloc_room := false;
- end;
- end;
- end;
-
- {
- Called by DEL_ROOM()
- put the room specified by n back on the free list
- zeroes n also, for convenience
- }
- procedure delete_room(var n: integer);
-
- begin
- if n <> 0 then begin
- getindex(I_ROOM);
- indx.inuse := indx.inuse - 1;
- indx.free[n] := true;
- putindex;
- n := 0;
- end;
- end;
-
-
-
- function alloc_log(var n: integer):boolean;
- var
- found: boolean;
-
- begin
- getindex(I_PLAYER);
- if indx.inuse = indx.top then begin
- freeindex;
- n := 0;
- alloc_log := false;
- writeln('There are too many monster players, you can''t find a space.');
- end else begin
- n := 1;
- found := false;
- while (not found) and (n <= indx.top) do begin
- if indx.free[n] then
- found := true
- else
- n := n + 1;
- end;
- if found then begin
- indx.free[n] := false;
- alloc_log := true;
- indx.inuse := indx.inuse + 1;
- putindex;
- end else begin
- freeindex;
- writeln('%serious error in alloc_log; notify Monster Manager');
- alloc_log := false;
- end;
- end;
- end;
-
- procedure delete_log(var n: integer);
-
- begin
- if n <> 0 then begin
- getindex(I_PLAYER);
- indx.inuse := indx.inuse - 1;
- indx.free[n] := true;
- putindex;
- n := 0;
- end;
- end;
-
-
- function lowcase(s: string):string;
- var
- sprime: string;
- i: integer;
-
- begin
- if length(s) = 0 then
- lowcase := ''
- else begin
- sprime := s;
- for i := 1 to length(s) do
- if sprime[i] in ['A'..'Z'] then
- sprime[i] := chr(ord('a')+(ord(sprime[i])-ord('A')));
- lowcase := sprime;
- end;
- end;
-
-
- { lookup a spell with disambiguation in the spell list }
-
- function lookup_spell(var n: integer;s:string): boolean;
- var
- i,poss,maybe,num: integer;
-
- begin
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to numspells do begin
- if s = spells[i] then
- num := i
- else if index(spells[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- n := num;
- lookup_spell := true;
- end else if maybe = 1 then begin
- n := poss;
- lookup_spell := true;
- end else if maybe > 1 then begin
- lookup_spell := false;
- end else begin
- lookup_spell := false;
- end;
- end;
-
-
- function lookup_user(var pnum: integer;s: string): boolean;
- var
- i,poss,maybe,num: integer;
-
- begin
- getuser;
- freeuser;
- getindex(I_PLAYER);
- freeindex;
-
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to indx.top do begin
- if not(indx.free[i]) then begin
- if s = user.idents[i] then
- num := i
- else if index(user.idents[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- end;
- if num <> 0 then begin
- pnum := num;
- lookup_user := true;
- end else if maybe = 1 then begin
- pnum := poss;
- lookup_user := true;
- end else if maybe > 1 then begin
- { writeln('-- Ambiguous direction'); }
- lookup_user := false;
- end else begin
- lookup_user := false;
- { writeln('-- Unknown direction'); }
- end;
- end;
-
-
- function alloc_obj(var n: integer):boolean;
- var
- found: boolean;
-
- begin
- getindex(I_OBJECT);
- if indx.inuse = indx.top then begin
- freeindex;
- n := 0;
- alloc_obj := false;
- writeln('All of the possible objects have been made.');
- end else begin
- n := 1;
- found := false;
- while (not found) and (n <= indx.top) do begin
- if indx.free[n] then
- found := true
- else
- n := n + 1;
- end;
- if found then begin
- indx.free[n] := false;
- alloc_obj := true;
- indx.inuse := indx.inuse + 1;
- putindex;
- end else begin
- freeindex;
- writeln('%serious error in alloc_obj; notify Monster Manager');
- alloc_obj := false;
- end;
- end;
- end;
-
-
- procedure delete_obj(var n: integer);
-
- begin
- if n <> 0 then begin
- getindex(I_OBJECT);
- indx.inuse := indx.inuse - 1;
- indx.free[n] := true;
- putindex;
- n := 0;
- end;
- end;
-
-
-
-
- function lookup_obj(var pnum: integer;s: string): boolean;
- var
- i,poss,maybe,num: integer;
- tmp: string;
-
- begin
- getobjnam;
- freeobjnam;
- getindex(I_OBJECT);
- freeindex;
-
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to indx.top do begin
- if not(indx.free[i]) then begin
- if s = objnam.idents[i] then
- num := i
- else if index(objnam.idents[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- end;
- if num <> 0 then begin
- pnum := num;
- lookup_obj := true;
- end else if maybe = 1 then begin
- pnum := poss;
- lookup_obj := true;
- end else if maybe > 1 then begin
- { writeln('-- Ambiguous direction'); }
- lookup_obj := false;
- end else begin
- lookup_obj := false;
- { writeln('-- Unknown direction'); }
- end;
- end;
-
-
-
- { returns true if object N is in this room }
-
- function obj_here(n: integer): boolean;
- var
- i: integer;
- found: boolean;
-
- begin
- i := 1;
- found := false;
- while (i <= maxobjs) and (not found) do begin
- if here.objs[i] = n then
- found := true
- else
- i := i + 1;
- end;
- obj_here := found;
- end;
-
-
-
-
- { returns true if object N is being held by the player }
-
- function obj_hold(n: integer): boolean;
- var
- i: integer;
- found: boolean;
-
- begin
- if n = 0 then
- obj_hold := false
- else begin
- i := 1;
- found := false;
- while (i <= maxhold) and (not found) do begin
- if here.people[myslot].holding[i] = n then
- found := true
- else
- i := i + 1;
- end;
- obj_hold := found;
- end;
- end;
-
-
-
- { return the slot of an object that is HERE }
- function find_obj(objnum: integer): integer;
- var
- i: integer;
-
- begin
- i := 1;
- find_obj := 0;
- while i <= maxobjs do begin
- if here.objs[i] = objnum then
- find_obj := i;
- i := i + 1;
- end;
- end;
-
-
-
- { similar to lookup_obj, but only returns true if the object is in
- this room or is being held by the player }
-
- function parse_obj(var n: integer; s: string;override: boolean := false): boolean;
- var
- slot: integer;
-
- begin
- if lookup_obj(n,s) then begin
- if obj_here(n) or obj_hold(n) then
-
- { took out a great block of code that wouldn't let
- parse_obj work if player couldn't see object }
-
- parse_obj := true;
- end else
- parse_obj := false;
- end;
-
-
-
-
- function lookup_pers(var pnum: integer;s: string): boolean;
- var
- i,poss,maybe,num: integer;
- pname: string;
-
- begin
- getpers;
- freepers;
- getindex(I_PLAYER);
- freeindex;
-
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to indx.top do begin
- if not(indx.free[i]) then begin
- pname := lowcase(pers.idents[i]);
-
- if s = pname then
- num := i
- else if index(pname,s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- end;
- if num <> 0 then begin
- pnum := num;
- lookup_pers := true;
- end else if maybe = 1 then begin
- pnum := poss;
- lookup_pers := true;
- end else if maybe > 1 then begin
- { writeln('-- Ambiguous direction'); }
- lookup_pers := false;
- end else begin
- lookup_pers := false;
- { writeln('-- Unknown direction'); }
- end;
- end;
-
-
-
- function parse_pers(var pnum: integer;s: string): boolean;
- var
- persnum: integer;
- i,poss,maybe,num: integer;
- pname: string;
-
- begin
- gethere;
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to maxpeople do begin
- { if here.people[i].username <> '' then begin }
-
- if here.people[i].kind > 0 then begin
- pname := lowcase(here.people[i].name);
-
- if s = pname then
- num := i
- else if index(pname,s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- end;
- if num <> 0 then begin
- persnum := num;
- parse_pers := true;
- end else if maybe = 1 then begin
- persnum := poss;
- parse_pers := true;
- end else if maybe > 1 then begin
- persnum := 0;
- parse_pers := false;
- end else begin
- persnum := 0;
- parse_pers := false;
- end;
- if persnum > 0 then begin
- if here.people[persnum].hiding > 0 then
- parse_pers := false
- else begin
- parse_pers := true;
- pnum := persnum;
- end;
- end;
- end;
-
-
-
-
-
- {
- Returns TRUE if player is owner of room n
- If no n is given default will be this room (location)
- }
- function is_owner(n: integer := 0;surpress:boolean := false): boolean;
-
- begin
- gethere(n);
- if (here.owner = userid) or (privd) then
- is_owner := true
- else begin
- is_owner := false;
- if not(surpress) then
- writeln('You are not the owner of this room.');
- end;
- end;
-
-
- function room_owner(n: integer): string;
-
- begin
- if n <> 0 then begin
- gethere(n);
- room_owner := here.owner;
- gethere; { restore old state! }
- end else
- room_owner := 'no room';
- end;
-
- {
- Returns TRUE if player is allowed to alter the exit
- TRUE if either this room or if target room is owned by player
- }
-
- function can_alter(dir: integer;room: integer := 0): boolean;
-
- begin
- gethere;
- if (here.owner=userid) or (privd) then begin
- can_alter := true
- end else begin
- if here.exits[dir].toloc > 0 then begin
- if room_owner(here.exits[dir].toloc) = userid then
- can_alter := true
- else
- can_alter := false;
- end else
- can_alter := false;
- end;
- end;
-
- function can_make(dir: integer;room: integer := 0): boolean;
-
- begin
- gethere(room); { 5 is accept door }
- if (here.exits[dir].toloc <> 0) then begin
- writeln('There is already an exit there. Use UNLINK or RELINK.');
- can_make := false;
- end else begin
- if (here.owner = userid) or { I'm the owner }
- (here.exits[dir].kind = 5) or { there's an accept }
- (privd) or { Monster Manager }
- (here.owner = '*') { disowned room }
- then
- can_make := true
- else begin
- can_make := false;
- writeln('You are not allowed to create an exit there.');
- end;
- end;
- end;
-
-
- {
- print a one liner
- }
- procedure print_line(n: integer);
-
- begin
- if n = DEFAULT_LINE then
- writeln('<default line>')
- else if n > 0 then begin
- getline(n);
- freeline;
- writeln(oneliner.theline);
- end;
- end;
-
-
-
- procedure print_desc(dsc: integer;default:string := '<no default supplied>');
- var
- i: integer;
-
- begin
- if dsc = DEFAULT_LINE then begin
- writeln(default);
- end else if dsc > 0 then begin
- getblock(dsc);
- freeblock;
- i := 1;
- while i <= block.desclen do begin
- writeln(block.lines[i]);
- i := i + 1;
- end;
- end else if dsc < 0 then begin
- print_line(abs(dsc));
- end;
- end;
-
-
-
-
- procedure make_line(var n: integer;prompt : string := '';limit:integer := 79);
- var
- s: string;
- ok: boolean;
-
- begin
- writeln('Type ** to leave line unchanged, * to make [no line]');
- grab_line(prompt,s);
- if s = '**' then begin
- writeln('No changes.');
- end else if s = '***' then begin
- n := DEFAULT_LINE;
- end else if s = '*' then begin
- if debug then
- writeln('%deleting line ',n:1);
- delete_line(n);
- end else if s = '' then begin
- if debug then
- writeln('%deleting line ',n:1);
- delete_line(n);
- end else if length(s) > limit then begin
- writeln('Please limit your string to ',limit:1,' characters.');
- end else begin
- if (n = 0) or (n = DEFAULT_LINE) then begin
- if debug then
- writeln('%makeline: allocating line');
- ok := alloc_line(n);
- end else
- ok := true;
-
- if ok then begin
- if debug then
- writeln('%ok in makeline');
- getline(n);
- oneliner.theline := s;
- putline;
-
- if debug then
- writeln('%completed putline in makeline');
- end;
- end;
- end;
-
-
- { translate a direction s [north, south, etc...] into the integer code }
-
- function lookup_dir(var dir: integer;s:string): boolean;
- var
- i,poss,maybe,num: integer;
-
- begin
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to maxexit do begin
- if s = direct[i] then
- num := i
- else if index(direct[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- dir := num;
- lookup_dir := true;
- end else if maybe = 1 then begin
- dir := poss;
- lookup_dir := true;
- end else if maybe > 1 then begin
- lookup_dir := false;
- { writeln('-- Ambiguous direction'); }
- end else begin
- lookup_dir := false;
- { writeln('-- Unknown direction'); }
- end;
- end;
-
-
- function lookup_show(var n: integer;s:string): boolean;
- var
- i,poss,maybe,num: integer;
-
- begin
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to numshow do begin
- if s = show[i] then
- num := i
- else if index(show[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- n := num;
- lookup_show := true;
- end else if maybe = 1 then begin
- n := poss;
- lookup_show := true;
- end else if maybe > 1 then begin
- lookup_show := false;
- { writeln('-- Ambiguous direction'); }
- end else begin
- lookup_show := false;
- { writeln('-- Unknown direction'); }
- end;
- end;
-
- function lookup_set(var n: integer;s:string): boolean;
- var
- i,poss,maybe,num: integer;
-
- begin
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to numset do begin
- if s = setkey[i] then
- num := i
- else if index(setkey[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- n := num;
- lookup_set := true;
- end else if maybe = 1 then begin
- n := poss;
- lookup_set := true;
- end else if maybe > 1 then begin
- lookup_set := false;
- end else begin
- lookup_set := false;
- end;
- end;
-
-
- function lookup_room(var n: integer; s: string): boolean;
- var
- found: boolean;
- top: integer;
-
- i,
- poss,
- maybe,
- num: integer;
-
- begin
- if s <> '' then begin
- s := lowcase(s); { case insensitivity }
- getnam;
- freenam;
- getindex(I_ROOM);
- freeindex;
- top := indx.top;
-
-
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to top do begin
- if s = nam.idents[i] then
- num := i
- else if index(nam.idents[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- lookup_room := true;
- n := num;
- end else if maybe = 1 then begin
- lookup_room := true;
- n := poss;
- end else if maybe > 1 then begin
- lookup_room := false;
- end else begin
- lookup_room := false;
- end;
-
- end else
- lookup_room := false;
- end;
-
-
- function exact_room(var n: integer;s: string): boolean;
- var
- match: boolean;
-
- begin
- if debug then
- writeln('%exact room: s = ',s);
- if lookup_room(n,s) then begin
- if nam.idents[n] = lowcase(s) then
- exact_room := true
- else
- exact_room := false;
- end else
- exact_room := false;
- end;
-
-
- function exact_pers(var n: integer;s: string): boolean;
- var
- match: boolean;
-
- begin
- if lookup_pers(n,s) then begin
- if lowcase(pers.idents[n]) = lowcase(s) then
- exact_pers := true
- else
- exact_pers := false;
- end else
- exact_pers := false;
- end;
-
-
- function exact_user(var n: integer;s: string): boolean;
- var
- match: boolean;
-
- begin
- if lookup_user(n,s) then begin
- if lowcase(user.idents[n]) = lowcase(s) then
- exact_user := true
- else
- exact_user := false;
- end else
- exact_user := false;
- end;
-
-
- function exact_obj(var n: integer;s: string): boolean;
- var
- match: boolean;
-
- begin
- if lookup_obj(n,s) then begin
- if objnam.idents[n] = lowcase(s) then
- exact_obj := true
- else
- exact_obj := false;
- end else
- exact_obj := false;
- end;
-
-
-
- {
- Return n as the direction number if s is a valid alias for an exit
- }
- function lookup_alias(var n: integer; s: string): boolean;
- var
- i,poss,maybe,num: integer;
-
- begin
- gethere;
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to maxexit do begin
- if s = here.exits[i].alias then
- num := i
- else if index(here.exits[i].alias,s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- n := num;
- lookup_alias := true;
- end else if maybe = 1 then begin
- n := poss;
- lookup_alias := true;
- end else if maybe > 1 then begin
- lookup_alias := false;
- end else begin
- lookup_alias := false;
- end;
- end;
-
-
- procedure exit_default(dir, kind: integer);
-
- begin
- case kind of
-
- 1: writeln('There is a passage leading ',direct[dir],'.');
- 2: writeln('There is a locked door leading ',direct[dir],'.');
- 5: case dir of
- north,south,east,west:
- writeln('A note on the ',direct[dir],' wall says "Your exit here."');
- up: writeln('A note on the ceiling says "Your exit here."');
- down: writeln('A note on the floor says "Your exit here."');
- end;
- otherwise writeln('There is an exit: ',direct[dir]);
- end;
- end;
-
-
- {
- Prints out the exits here for DO_LOOK()
- }
- procedure show_exits;
- var
- i: integer;
- one: boolean;
- cansee: boolean;
-
- begin
- one := false;
- for i := 1 to maxexit do begin
- if (here.exits[i].toloc <> 0) or { there is an exit }
- (here.exits[i].kind = 5) then begin { there could be an exit }
-
- if (here.exits[i].hidden = 0) or
- (found_exit[i]) then
- cansee := true
- else
- cansee := false;
-
- if here.exits[i].kind = 6 then begin
- { door kind only visible with object }
- if obj_hold( here.exits[i].objreq ) then
- cansee := true
- else
- cansee := false;
- end;
-
- if cansee then begin
- if here.exits[i].exitdesc = DEFAULT_LINE then begin
- exit_default(i,here.exits[i].kind);
- { give it direction and type }
- one := true;
- end else if here.exits[i].exitdesc > 0 then begin
- print_line(here.exits[i].exitdesc);
- one := true;
- end;
- end;
- end;
- end;
- if one then
- writeln;
- end;
-
-
- procedure setevent;
-
- begin
- getevent;
- freeevent;
- myevent := event.point;
- end;
-
-
-
- function isnum(s: string): boolean;
- var
- i: integer;
-
- begin
- isnum := true;
- if length(s) < 1 then
- isnum := false
- else begin
- i := 1;
- while i <= length(s) do begin
- if not (s[i] in ['0'..'9']) then
- isnum := false;
- i := i + 1;
- end;
- end;
- end;
-
- function number(s: string): integer;
- var
- i: integer;
-
- begin
- if (length(s) < 1) or not(s[1] in ['0'..'9']) then
- number := 0
- else begin
- readv(s,i);
- number := i;
- end;
- end;
-
-
-
- procedure log_event( send: integer := 0; { slot of sender }
- act:integer; { what event occurred }
- targ: integer := 0; { target of event }
- p: integer := 0; { expansion parameter }
- s: string := ''; { string for messages }
- room: integer := 0 { room to log event in }
- );
-
- begin
- if room = 0 then
- room := location;
- getevent(room);
- event.point := event.point + 1;
- if debug then
- writeln('%logging event ',act:1,' to point ',event.point:1);
- if event.point > maxevent then
- event.point := 1;
- with event.evnt[event.point] do begin
- sender := send;
- action := act;
- target := targ;
- parm := p;
- msg := s;
- loc := room;
- end;
- putevent;
- end;
-
- procedure log_action(theaction,thetarget: integer);
-
- begin
- if debug then
- writeln('%log_action(',theaction:1,',',thetarget:1,')');
- getroom;
- here.people[myslot].act := theaction;
- here.people[myslot].targ := thetarget;
- putroom;
-
- logged_act := true;
- log_event(myslot,E_ACTION,thetarget,theaction,myname);
- end;
-
-
- function desc_action(theaction,thetarget: integer): string;
- var
- s: string;
-
- begin
- case theaction of { use command mnemonics }
- look: s:= ' looking around the room.';
- form: s:= ' creating a new room.';
- desc: s:= ' editing the description to this room.';
- e_detail: s := ' adding details to the room.';
- c_custom: s := ' customizing an exit here.';
- e_custroom:s := ' customizing this room.';
- e_program: s := ' customizing an object.';
- c_self: s := ' editing a self-description.';
- e_usecrystal: s := ' hunched over a crystal orb, immersed in its glow.';
- link: s := ' creating an exit here.';
- c_system: s := ' in system maintenance mode.';
-
- otherwise s := ' here.'
- end;
- desc_action := s;
- end;
-
-
- function protected(n: integer := 0): boolean;
-
- begin
- if n = 0 then
- n := myslot;
- if here.people[n].act in [e_detail,c_custom,
- e_custroom,e_program,
- c_self,c_system] then
- protected := true
- else
- protected := false;
- end;
-
-
-
- {
- user procedure to designate an exit for acceptance of links
- }
- procedure do_accept(s: string);
- var
- dir: integer;
-
- begin
- if lookup_dir(dir,s) then begin
- if can_make(dir) then begin
- getroom;
- here.exits[dir].kind := 5;
- putroom;
-
- log_event(myslot,E_ACCEPT,0,0);
- writeln('Someone will be able to make an exit ',direct[dir],'.');
- end;
- end else
- writeln('To allow others to make an exit, type ACCEPT <direction of exit>.');
- end;
-
-
- {
- User procedure to refuse an exit for links
- Note: may be unlink
- }
- procedure do_refuse(s: string);
- var
- dir: integer;
- ok: boolean;
-
- begin
- if not(is_owner) then
- { is_owner prints error message itself }
- else if lookup_dir(dir,s) then begin
- getroom;
- with here.exits[dir] do begin
- if (toloc = 0) and (kind = 5) then begin
- kind := 0;
- ok := true;
- end else
- ok := false;
- end;
- putroom;
- if ok then begin
- log_event(myslot,E_REFUSE,0,0);
- writeln('Exits ',direct[dir],' will be refused.');
- end else
- writeln('Exits were not being accepted there.');
- end else
- writeln('To undo an Accept, type REFUSE <direction>.');
- end;
-
-
-
- function systime:string;
- var
- hourstring: string;
- hours: integer;
- thetime: packed array[1..11] of char;
- dayornite: string;
-
- begin
- time(thetime);
- if thetime[1] = ' ' then
- hours := ord(thetime[2]) - ord('0')
- else
- hours := (ord(thetime[1]) - ord('0'))*10 +
- (ord(thetime[2]) - ord('0'));
-
- if hours < 12 then
- dayornite := 'am'
- else
- dayornite := 'pm';
- if hours >= 13 then
- hours := hours - 12;
- if hours = 0 then
- hours := 12;
-
- writev(hourstring,hours:2);
-
- systime := hourstring + ':' + thetime[4] + thetime[5] + dayornite;
- end;
-
-
-
- { substitute a parameter string for the # sign in the source string }
- function subs_parm(s,parm: string): string;
- var
- right,left: string;
- i: integer; { i is point to break at }
-
- begin
- i := index(s,'#');
- if (i > 0) and ((length(s) + length(parm)) <= 80) then begin
- if i >= length(s) then begin
- right := '';
- left := s;
- end else if i < 1 then begin
- right := s;
- left := '';
- end else begin
- right := substr(s,i+1,length(s)-i);
- left := substr(s,1,i);
- end;
- if length(left) <= 1 then
- left := ''
- else
- left := substr(left,1,length(left)-1);
-
- subs_parm := left + parm + right;
- end else begin
- subs_parm := s;
- end;
- end;
-
-
- procedure time_health;
-
- begin
- if healthcycle > 0 then begin { how quickly they heal }
- if myhealth < 7 then begin { heal a little bit }
- myhealth := myhealth + 1;
-
- getroom;
- here.people[myslot].health := myhealth;
- putroom;
-
- {show new health rating }
- case myhealth of
- 9: writeln('You are now in exceptional health.');
- 8: writeln('You feel much stronger. You are in better than average condition.');
- 7: writeln('You are now in perfect health.');
- 6: writeln('You only feel a little bit dazed now.');
- 5: begin
- writeln('You only have some minor cuts and abrasions now. Most of your serious wounds');
- writeln('have healed.');
- end;
- 4: writeln('You are only suffering from some minor wounds now.');
- 3: writeln('Your most serious wounds have healed, but you are still in bad shape.');
- 2: writeln('You have healed somewhat, but are still very badly wounded.');
- 1: writeln('You are in critical condition, but there may be hope.');
- 0: writeln('are still dead.');
- otherwise writeln('You don''t seem to be in any condition at all.');
- end;
-
- putchars(chr(10)+old_prompt+line);
-
- end;
- healthcycle := 0;
- end else
- healthcycle := healthcycle + 1;
- end;
-
-
- procedure time_noises;
- var
- n: integer;
-
- begin
- if rnd100 <= 2 then begin
- n := rnd100;
- if n in [0..40] then
- log_event(0,E_NOISES,rnd100,0)
- else if n in [41..60] then
- log_event(0,E_ALTNOISE,rnd100,0);
- end;
- end;
-
-
- procedure time_trapdoor(silent: boolean);
- var
- fall: boolean;
-
- begin
- if rnd100 < here.trapchance then begin
- { trapdoor fires! }
-
- if here.trapto > 0 then begin
- { logged action should cover {protected) }
- if {(protected) or} (logged_act) then
- fall := false
- else if here.magicobj = 0 then
- fall := true
- else if obj_hold(here.magicobj) then
- fall := false
- else
- fall := true;
- end else
- fall := false;
-
- if fall then begin
- do_exit(here.trapto);
- if not(silent) then
- putchars(chr(10)+old_prompt+line);
- end;
- end;
- end;
-
-
- procedure time_midnight;
-
- begin
- if systime = '12:00am' then
- log_event(0,E_MIDNIGHT,rnd100,0);
- end;
-
-
- { cause random events to occurr (ha ha ha) }
-
- procedure rnd_event(silent: boolean := false);
- var
- n: integer;
-
- begin
- if rndcycle = 200 then begin { inside here 3 times/min }
-
- time_noises;
- time_health;
- time_trapdoor(silent);
- time_midnight;
-
- rndcycle := 0;
- end else
- rndcycle := rndcycle + 1;
- end;
-
-
- procedure do_die;
- var
- some: boolean;
-
- begin
- writeln;
- writeln(' *** You have died ***');
- writeln;
- some := drop_everything;
- myhealth := 7;
- take_token(myslot,location);
- log_event(0,E_DIED,0,0,myname);
- if put_token(2,myslot) then begin
- location := 2;
- inmem := false;
- setevent;
- { log entry to death loc }
- { perhaps turn off refs to other people }
- end else begin
- writeln('The Monster universe regrets to inform you that you cannot be ressurected at');
- writeln('the moment.');
- halt;
- end;
- end;
-
-
- procedure poor_health(p: integer);
- var
- some: boolean;
-
- begin
- if myhealth > p then begin
- myhealth := myhealth - 1;
- getroom;
- here.people[myslot].health := myhealth;
- putroom;
- log_event(myslot,E_WEAKER,myhealth,0);
-
- { show new health rating }
- write('You ');
- case here.people[myslot].health of
- 9: writeln('are still in exceptional health.');
- 8: writeln('feel weaker, but are in better than average condition.');
- 7: writeln('are somewhat weaker, but are in perfect health.');
- 6: writeln('feel a little bit dazed.');
- 5: writeln('have some minor cuts and abrasions.');
- 4: writeln('have some wounds, but are still fairly strong.');
- 3: writeln('are suffering from some serious wounds.');
- 2: writeln('are very badly wounded.');
- 1: writeln('have many serious wounds, and are near death.');
- 0: writeln('are dead.');
- otherwise writeln('don''t seem to be in any condition at all.');
- end;
- end else begin { they died }
- do_die;
- end;
- end;
-
-
-
- { count objects here }
-
- function find_numobjs: integer;
- var
- sum,i: integer;
-
- begin
- sum := 0;
- for i := 1 to maxobjs do
- if here.objs[i] <> 0 then
- sum := sum + 1;
- find_numobjs := sum;
- end;
-
-
-
- { optional parameter is slot of player's objects to count }
-
- function find_numhold(player: integer := 0): integer;
- var
- sum,i: integer;
-
- begin
- if player = 0 then
- player := myslot;
-
- sum := 0;
- for i := 1 to maxhold do
- if here.people[player].holding[i] <> 0 then
- sum := sum + 1;
- find_numhold := sum;
- end;
-
-
-
-
- procedure take_hit(p: integer);
- var
- i: integer;
-
- begin
- if p > 0 then begin
- if rnd100 < (55 + (p-1) * 30) then { chance that they're hit }
- poor_health(p);
-
- if find_numobjs < maxobjs + 1 then begin
- { maybe they drop something if they're hit }
- for i := 1 to p do
- maybe_drop;
- end;
- end;
- end;
-
-
- function punch_force(sock: integer): integer;
- var
- p: integer;
-
- begin
- if sock in [2,3,6,7,8,11,12] then { no punch or a graze }
- p := 0
- else if sock in [4,9,10] then { hard punches }
- p := 2
- else { 1,5,13,14,15 }
- p := 1; { all others are medium punches }
- punch_force := p;
- end;
-
- procedure put_punch(sock: integer;s: string);
-
- begin
- case sock of
- 1: writeln('You deliver a quick jab to ',s,'''s jaw.');
- 2: writeln('You swing at ',s,' and miss.');
- 3: writeln('A quick punch, but it only grazes ',s,'.');
- 4: writeln(s,' doubles over after your jab to the stomach.');
- 5: writeln('Your punch lands square on ',s,'''s face!');
- 6: writeln('You swing wild and miss.');
- 7: writeln('A good swing, but it misses ',s,' by a mile!');
- 8: writeln('Your punch is blocked by ',s,'.');
- 9: writeln('Your roundhouse blow sends ',s,' reeling.');
- 10:writeln('You land a solid uppercut on ',s,'''s chin.');
- 11:writeln(s,' fends off your blow.');
- 12:writeln(s,' ducks and avoids your punch.');
- 13:writeln('You thump ',s,' in the ribs.');
- 14:writeln('You catch ',s,'''s face on your elbow.');
- 15:writeln('You knock the wind out of ',s,' with a punch to the chest.');
- end;
- end;
-
-
- procedure get_punch(sock: integer;s: string);
-
- begin
- case sock of
- 1: writeln(s,' delivers a quick jab to your jaw!');
- 2: writeln(s,' swings at you but misses.');
- 3: writeln(s,'''s fist grazes you.');
- 4: writeln('You double over after ',s,' lands a mean jab to your stomach!');
- 5: writeln('You see stars as ',s,' bashes you in the face.');
- 6: writeln('You only feel the breeze as ',s,' swings wildly.');
- 7: writeln(s,'''s swing misses you by a yard.');
- 8: writeln('With lightning reflexes you block ',s,'''s punch.');
- 9: writeln(s,'''s blow sends you reeling.');
- 10:writeln('Your head snaps back from ',s,'''s uppercut!');
- 11:writeln('You parry ',s,'''s attack.');
- 12:writeln('You duck in time to avoid ',s,'''s punch.');
- 13:writeln(s,' thumps you hard in the ribs.');
- 14:writeln('Your vision blurs as ',s,' elbows you in the head.');
- 15:writeln(s,' knocks the wind out of you with a punch to your chest.');
- end;
- end;
-
- procedure view_punch(a,b: string;p: integer);
-
- begin
- case p of
- 1: writeln(a,' jabs ',b,' in the jaw.');
- 2: writeln(a,' throws a wild punch at the air.');
- 3: writeln(a,'''s fist barely grazes ',b,'.');
- 4: writeln(b,' doubles over in pain with ',a,'''s punch');
- 5: writeln(a,' bashes ',b,' in the face.');
- 6: writeln(a,' takes a wild swing at ',b,' and misses.');
- 7: writeln(a,' swings at ',b,' and misses by a yard.');
- 8: writeln(b,'''s punch is blocked by ',a,'''s quick reflexes.');
- 9: writeln(b,' is sent reeling from a punch by ',a,'.');
- 10:writeln(a,' lands an uppercut on ',b,'''s head.');
- 11:writeln(b,' parrys ',a,'''s attack.');
- 12:writeln(b,' ducks to avoid ',a,'''s punch.');
- 13:writeln(a,' thumps ',b,' hard in the ribs.');
- 14:writeln(a,'''s elbow connects with ',b,'''s head.');
- 15:writeln(a,' knocks the wind out of ',b,'.');
- end;
- end;
-
-
-
-
- procedure desc_health(n: integer;header:shortstring := '');
-
- begin
- if header = '' then
- write(here.people[n].name,' ')
- else
- write(header);
-
- case here.people[n].health of
- 9: writeln('is in exceptional health, and looks very strong.');
- 8: writeln('is in better than average condition.');
- 7: writeln('is in perfect health.');
- 6: writeln('looks a little dazed.');
- 5: writeln('has some minor cuts and abrasions.');
- 4: writeln('has some minor wounds.');
- 3: writeln('is suffering from some serious wounds.');
- 2: writeln('is very badly wounded.');
- 1: writeln('has many serious wounds, and is near death.');
- 0: writeln('is dead.');
- otherwise writeln('doesn''t seem to be in any condition at all.');
- end;
- end;
-
-
- function obj_part(objnum: integer;doread: boolean := TRUE): string;
- var
- s: string;
-
- begin
- if doread then begin
- getobj(objnum);
- freeobj;
- end;
- s := obj.oname;
- case obj.particle of
- 0:;
- 1: s := 'a ' + s;
- 2: s := 'an ' + s;
- 3: s := 'some ' + s;
- 4: s := 'the ' + s;
- end;
- obj_part := s;
- end;
-
-
- procedure print_subs(n: integer;s: string);
-
- begin
- if (n > 0) and (n <> DEFAULT_LINE) then begin
- getline(n);
- freeline;
- writeln(subs_parm(oneliner.theline,s));
- end else if n = DEFAULT_LINE then
- writeln('%<default line> in print_subs');
- end;
-
-
-
- { print out a (up to) 10 line description block, substituting string s for
- up to one occurance of # per line }
-
- procedure block_subs(n: integer;s: string);
- var
- p,i: integer;
-
- begin
- if n < 0 then
- print_subs(abs(n),s)
- else if (n > 0) and (n <> DEFAULT_LINE) then begin
- getblock(n);
- freeblock;
- i := 1;
- while i <= block.desclen do begin
- p := index(block.lines[i],'#');
- if (p > 0) then
- writeln(subs_parm(block.lines[i],s))
- else
- writeln(block.lines[i]);
- i := i + 1;
- end;
- end;
- end;
-
-
- procedure show_noises(n: integer);
-
- begin
- if n < 33 then
- writeln('There are strange noises coming from behind you.')
- else if n < 66 then
- writeln('You hear strange rustling noises behind you.')
- else
- writeln('There are faint noises coming from behind you.');
- end;
-
-
- procedure show_altnoise(n: integer);
-
- begin
- if n < 33 then
- writeln('A chill wind blows, ruffling your clothes and chilling your bones.')
- else if n < 66 then
- writeln('Muffled scuffling sounds can be heard behind you.')
- else
- writeln('A loud crash can be heard in the distance.');
- end;
-
-
- procedure show_midnight(n: integer;var printed: boolean);
-
- begin
- if midnight_notyet then begin
- if n < 50 then begin
- writeln('A voice booms out of the air from all around you!');
- writeln('The voice says, " It is now midnight. "');
- end else begin
- writeln('You hear a clock chiming in the distance.');
- writeln('It rings twelve times for midnight.');
- end;
- midnight_notyet := false;
- end else
- printed := false;
- end;
-
-
-
-
- procedure handle_event(var printed: boolean);
- var
- n,send,act,targ,p: integer;
- s: string;
- sendname: string;
-
- begin
- printed := true;
- if debug then
- writeln('%handling event ',myevent);
- with event.evnt[myevent] do begin
- send := sender;
- act := action;
- targ := target;
- p := parm;
- s := msg;
- end;
- if send <> 0 then
- sendname := here.people[send].name
- else
- sendname := '<Unknown>';
-
- case act of
- E_EXIT: begin
- if here.exits[targ].goin = DEFAULT_LINE then
- writeln(s,' has gone ',direct[targ],'.')
- else if (here.exits[targ].goin <> 0) and
- (here.exits[targ].goin <> DEFAULT_LINE) then begin
- block_subs(here.exits[targ].goin,s);
- end else
- printed := false;
- end;
- E_ENTER: begin
- if here.exits[targ].comeout = DEFAULT_LINE then
- writeln(s,' has come into the room from: ',direct[targ])
- else if (here.exits[targ].comeout <> 0) and
- (here.exits[targ].comeout <> DEFAULT_LINE) then begin
- block_subs(here.exits[targ].comeout,s);
- end else
- printed := false;
- end;
- E_BEGIN:writeln(s,' appears in a brilliant burst of multicolored light.');
- E_QUIT:writeln(s,' vanishes in a brilliant burst of multicolored light.');
- E_SAY: begin
- if length(s) + length(sendname) > 73 then begin
- writeln(sendname,' says,');
- writeln('"',s,'"');
- end else begin
- if (rnd100 < 50) or (length(s) > 50) then
- writeln(sendname,': "',s,'"')
- else
- writeln(sendname,' says, "',s,'"');
- end;
- end;
- E_HIDESAY: begin
- writeln('An unidentified voice speaks to you:');
- writeln('"',s,'"');
- end;
- E_SETNAM: writeln(s);
- E_POOFIN: writeln('In an explosion of orange smoke ',s,' poofs into the room.');
- E_POOFOUT: writeln(s,' vanishes from the room in a cloud of orange smoke.');
- E_DETACH: begin
- writeln(s,' has destroyed the exit ',direct[targ],'.');
- end;
- E_EDITDONE:begin
- writeln(sendname,' is done editing the room description.');
- end;
- E_NEWEXIT: begin
- writeln(s,' has created an exit here.');
- end;
- E_CUSTDONE:begin
- writeln(sendname,' is done customizing an exit here.');
- end;
- E_SEARCH: writeln(sendname,' seems to be looking for something.');
- E_FOUND: writeln(sendname,' appears to have found something.');
- E_DONEDET:begin
- writeln(sendname,' is done adding details to the room.');
- end;
- E_ROOMDONE: begin
- writeln(sendname,' is finished customizing this room.');
- end;
- E_OBJDONE: begin
- writeln(sendname,' is finished customizing an object.');
- end;
- E_UNHIDE:writeln(sendname,' has stepped out of the shadows.');
- E_FOUNDYOU: begin
- if targ = myslot then begin { found me! }
- writeln('You''ve been discovered by ',sendname,'!');
- hiding := false;
- getroom;
- { they're not hidden anymore } here.people[myslot].hiding := 0;
- putroom;
- end else
- writeln(sendname,' has found ',here.people[targ].name,' hiding in the shadows!');
- end;
- E_PUNCH: begin
- if targ = myslot then begin { punched me! }
- get_punch(p,sendname);
- take_hit( punch_force(p) );
- { relic, but not harmful } ping_answered := true;
- healthcycle := 0;
- end else
- view_punch(sendname,here.people[targ].name,p);
- end;
- E_MADEOBJ: writeln(s);
- E_GET: writeln(s);
- E_DROP: begin
- writeln(s);
- if here.objdesc <> 0 then
- print_subs(here.objdesc,obj_part(p));
- end;
- E_BOUNCEDIN: begin
- if (targ = 0) or (targ = DEFAULT_LINE) then
- writeln(obj_part(p),' has bounced into the room.')
- else begin
- print_subs(targ,obj_part(p));
- end;
- end;
- E_DROPALL: writeln('Some objects drop to the ground.');
- E_EXAMINE: writeln(s);
- E_IHID: writeln(sendname,' has hidden in the shadows.');
- E_NOISES: begin
- if (here.rndmsg = 0) or
- (here.rndmsg = DEFAULT_LINE) then begin
- show_noises(targ);
- end else
- print_line(here.rndmsg);
- end;
- E_ALTNOISE: begin
- if (here.xmsg2 = 0) or
- (here.xmsg2 = DEFAULT_LINE) then
- show_altnoise(targ)
- else
- block_subs(here.xmsg2,myname);
- end;
- E_REALNOISE: show_noises(targ);
- E_HIDOBJ: writeln(sendname,' has hidden the ',s,'.');
- E_PING: begin
- if targ = myslot then begin
- writeln(sendname,' is trying to ping you.');
- log_event(myslot,E_PONG,send,0);
- end else
- writeln(sendname,' is pinging ',here.people[targ].name,'.');
- end;
- E_PONG: begin
- ping_answered := true;
- end;
- E_HIDEPUNCH: begin
- if targ = myslot then begin
- writeln(sendname,' pounces on you from the shadows!');
- take_hit(2);
- end else begin
- writeln(sendname,' jumps out of the shadows and attacks ',here.people[targ].name,'.');
- end;
- end;
- E_SLIPPED: begin
- writeln('The ',s,' has slipped from ',
- sendname,'''s hands.');
- end;
- E_HPOOFOUT:begin
- if rnd100 > 50 then
- writeln('Great wisps of orange smoke drift out of the shadows.')
- else
- printed := false;
- end;
- E_HPOOFIN:begin
- if rnd100 > 50 then
- writeln('Some wisps of orange smoke drift about in the shadows.')
- else
- printed := false;
- end;
- E_FAILGO: begin
- if targ > 0 then begin
- write(sendname,' has failed to go ');
- writeln(direct[targ],'.');
- end;
- end;
- E_TRYPUNCH: begin
- if targ = myslot then
- writeln(sendname,' fails to punch you.')
- else
- writeln(sendname,' fails to punch ',here.people[targ].name,'.');
- end;
- E_PINGONE:begin
- if targ = myslot then begin { ohoh---pinged away }
- writeln('The Monster program regrets to inform you that a destructive ping has');
- writeln('destroyed your existence. Please accept our apologies.');
- halt; { ugggg }
- end else
- writeln(s,' shimmers and vanishes from sight.');
- end;
- E_CLAIM: writeln(sendname,' has claimed this room.');
- E_DISOWN: writeln(sendname,' has disowned this room.');
- E_WEAKER: begin
- { inmem := false;
- gethere; }
-
- here.people[send].health := targ;
-
- { This is a hack for efficiency so we don't read the room record twice;
- we need the current data now for desc_health, but checkevents, our caller,
- is about to re-read it anyway; we make an incremental fix here so desc_health
- is happy, then checkevents will do the real read later }
-
- desc_health(send);
- end;
- E_OBJCLAIM: writeln(sendname,' is now the owner of the ',s,'.');
- E_OBJDISOWN: writeln(sendname,' has disowned the object ',s,'.');
- E_SELFDONE: writeln(sendname,'''s self-description is finished.');
- E_WHISPER: begin
- if targ = myslot then begin
- if length(s) < 39 then
- writeln(sendname,' whispers to you, "',s,'"')
- else begin
- writeln(sendname,' whispers something to you:');
- write(sendname,' whispers, ');
- if length(s) > 50 then
- writeln;
- writeln('"',s,'"');
- end;
- end else if (privd) or (rnd100 > 85) then begin
- writeln('You overhear ',sendname,' whispering to ',here.people[targ].name,'!');
- write(sendname,' whispers, ');
- if length(s) > 50 then
- writeln;
- writeln('"',s,'"');
- end else
- writeln(sendname,' is whispering to ',here.people[targ].name,'.');
- end;
- E_WIELD: writeln(sendname,' is now wielding the ',s,'.');
- E_UNWIELD: writeln(sendname,' is no longer wielding the ',s,'.');
- E_WEAR: writeln(sendname,' is now wearing the ',s,'.');
- E_UNWEAR: writeln(sendname,' has taken off the ',s,'.');
- E_DONECRYSTALUSE: begin
- writeln(sendname,' emerges from the glow of the crystal.');
- writeln('The orb becomes dark.');
- end;
- E_DESTROY: writeln(s);
- E_OBJPUBLIC: writeln('The object ',s,' is now public.');
- E_SYSDONE: writeln(sendname,' is no longer in system maintenance mode.');
- E_UNMAKE: writeln(sendname,' has unmade ',s,'.');
- E_LOOKDETAIL: writeln(sendname,' is looking at the ',s,'.');
- E_ACCEPT: writeln(sendname,' has accepted an exit here.');
- E_REFUSE: writeln(sendname,' has refused an Accept here.');
- E_DIED: writeln(s,' expires and vanishes in a cloud of greasy black smoke.');
- E_LOOKYOU: begin
- if targ = myslot then begin
- writeln(sendname,' is looking at you.')
- end else
- writeln(sendname,' looks at ',here.people[targ].name,'.');
- end;
- E_LOOKSELF: writeln(sendname,' is making a self-appraisal.');
- E_FAILGET: writeln(sendname,' fails to get ',obj_part(targ),'.');
- E_FAILUSE: writeln(sendname,' fails to use ',obj_part(targ),'.');
- E_CHILL: if (targ = 0) or (targ = DEFAULT_LINE) then
- writeln('A chill wind blows over you.')
- else
- print_desc(targ);
- E_NOISE2:begin
- case targ of
- 1: writeln('Strange, gutteral noises sound from everywhere.');
- 2: writeln('A chill wind blows past you, almost whispering as it ruffles your clothes.');
- 3: writeln('Muffled voices speak to you from the air!');
- otherwise writeln('The air vibrates with a chill shudder.');
- end;
- end;
- E_INVENT: writeln(sendname,' is taking inventory.');
- E_POOFYOU: begin
- if targ = myslot then begin
- writeln;
- writeln(sendname,' directs a firey burst of bluish energy at you!');
- writeln('Suddenly, you find yourself hurtling downwards through misty orange clouds.');
- writeln('Your descent slows, the smoke clears, and you find yourself in a new place...');
- xpoof(p);
- writeln;
- end else begin
- writeln(sendname,' directs a firey burst of energy at ',here.people[targ].name,'!');
- writeln('A thick burst of orange smoke results, and when it clears, you see');
- writeln('that ',here.people[targ].name,' is gone.');
- end;
- end;
- E_WHO: begin
- case p of
- 0: writeln(sendname,' produces a "who" list and reads it.');
- 1: writeln(sendname,' is seeing who''s playing Monster.');
- otherwise writeln(sendname,' checks the "who" list.');
- end;
- end;
- E_PLAYERS:begin
- writeln(sendname,' checks the "players" list.');
- end;
- E_VIEWSELF: writeln(sendname,' is reading ',s,'''s self-description.');
- E_MIDNIGHT: show_midnight(targ,printed);
-
- E_ACTION:writeln(sendname,' is',desc_action(p,targ));
- otherwise writeln('*** Bad Event ***');
- end;
- end;
-
-
- [global]
- procedure checkevents(silent: boolean := false);
- var
- gotone: boolean;
- tmp,printed: boolean;
-
- begin
- getevent;
- freeevent;
-
- event := eventfile^;
- gotone := false;
- printed := false;
- while myevent <> event.point do begin
- myevent := myevent + 1;
- if myevent > maxevent then
- myevent := 1;
-
- if debug then begin
- writeln('%checking event ',myevent);
- if event.evnt[myevent].loc = location then
- writeln(' - event here')
- else
- writeln(' - event elsewhere');
- writeln(' - event number = ',event.evnt[myevent].action:1);
- end;
-
- if (event.evnt[myevent].loc = location) then begin
- if (event.evnt[myevent].sender <> myslot) then begin
-
- { if sent by me don't look at it }
- { will use global record event }
- handle_event(tmp);
- if tmp then
- printed := true;
-
- inmem := false; { re-read important data that }
- gethere; { may have been altered }
-
- gotone := true;
- end;
- end;
- end;
- if (printed) and (gotone) and not(silent) then begin
- putchars(chr(10)+chr(13)+old_prompt+line);
- end;
-
- rnd_event(silent);
- end;
-
-
-
- { count the number of people in this room; assumes a gethere has been done }
-
- function find_numpeople: integer;
- var
- sum,i: integer;
-
- begin
- sum := 0;
- for i := 1 to maxpeople do
- if here.people[i].kind > 0 then
- { if here.people[i].username <> '' then }
- sum := sum + 1;
- find_numpeople := sum;
- end;
-
-
-
- { don't give them away, but make noise--maybe
- percent is percentage chance that they WON'T make any noise }
-
- procedure noisehide(percent: integer);
-
- begin
- { assumed gethere; }
- if (hiding) and (find_numpeople > 1) then begin
- if rnd100 > percent then
- log_event(myslot,E_REALNOISE,rnd100,0);
- { myslot: don't tell them they made noise }
- end;
- end;
-
-
-
- function checkhide: boolean;
-
- begin
- if (hiding) then begin
- checkhide := false;
- noisehide(50);
- writeln('You can''t do that while you''re hiding.');
- end else
- checkhide := true;
- end;
-
-
-
- procedure clear_command;
-
- begin
- if logged_act then begin
- getroom;
- here.people[myslot].act := 0;
- putroom;
- logged_act := false;
- end;
- end;
-
- { forward procedure take_token(aslot, roomno: integer); }
- procedure take_token;
- { remove self from a room's people list }
-
- begin
- getroom(roomno);
- with here.people[aslot] do begin
- kind := 0;
- username:= '';
- name := '';
- end;
- putroom;
- end;
-
-
- { fowrard function put_token(room: integer;var aslot:integer;
- hidelev:integer := 0):boolean;
- put a person in a room's people list
- returns myslot }
- function put_token;
- var
- i,j: integer;
- found: boolean;
- savehold: array[1..maxhold] of integer;
-
- begin
- if first_puttoken then begin
- for i := 1 to maxhold do
- savehold[i] := 0;
- first_puttoken := false;
- end else begin
- gethere;
- for i := 1 to maxhold do
- savehold[i] := here.people[myslot].holding[i];
- end;
-
- getroom(room);
- i := 1;
- found := false;
- while (i <= maxpeople) and (not found) do begin
- if here.people[i].name = '' then
- found := true
- else
- i := i + 1;
- end;
- put_token := found;
- if found then begin
- here.people[i].kind := 1; { I'm a real player }
- here.people[i].name := myname;
- here.people[i].username := userid;
- here.people[i].hiding := hidelev;
- { hidelev is zero for most everyone
- unless you want to poof in and remain hidden }
-
- here.people[i].wearing := mywear;
- here.people[i].wielding := mywield;
- here.people[i].health := myhealth;
- here.people[i].self := myself;
-
- here.people[i].act := 0;
-
- for j := 1 to maxhold do
- here.people[i].holding[j] := savehold[j];
- putroom;
-
- aslot := i;
- for j := 1 to maxexit do { haven't found any exits in }
- found_exit[j] := false; { the new room }
-
- { note the user's new location in the logfile }
- getint(N_LOCATION);
- anint.int[mylog] := room;
- putint;
- end else
- freeroom;
- end;
-
- procedure log_exit(direction,room,sender_slot: integer);
-
- begin
- log_event(sender_slot,E_EXIT,direction,0,myname,room);
- end;
-
- procedure log_entry(direction,room,sender_slot: integer);
-
- begin
- log_event(sender_slot,E_ENTER,direction,0,myname,room);
- end;
-
- procedure log_begin(room:integer := 1);
-
- begin
- log_event(0,E_BEGIN,0,0,myname,room);
- end;
-
- procedure log_quit(room:integer;dropped:boolean);
-
- begin
- log_event(0,E_QUIT,0,0,myname,room);
- if dropped then
- log_event(0,E_DROPALL,0,0,myname,room);
- end;
-
-
-
-
- { return the number of people you can see here }
-
- function n_can_see: integer;
- var
- sum: integer;
- i: integer;
- selfslot: integer;
-
- begin
- if here.locnum = location then
- selfslot := myslot
- else
- selfslot := 0;
-
- sum := 0;
- for i := 1 to maxpeople do
- if ( i <> selfslot ) and
- ( length(here.people[i].name) > 0 ) and
- ( here.people[i].hiding = 0 ) then
- sum := sum + 1;
- n_can_see := sum;
- if debug then
- writeln('%n_can_see = ',sum:1);
- end;
-
-
-
- function next_can_see(var point: integer): string;
- var
- found: boolean;
- selfslot: integer;
-
- begin
- if here.locnum <> location then
- selfslot := 0
- else
- selfslot := myslot;
- found := false;
- while (not found) and (point <= maxpeople) do begin
- if (point <> selfslot) and
- (length(here.people[point].name) > 0) and
- (here.people[point].hiding = 0) then
- found := true
- else
- point := point + 1;
- end;
-
- if found then begin
- next_can_see := here.people[point].name;
- point := point + 1;
- end else begin
- next_can_see := myname; { error! error! }
- writeln('%searching error in next_can_see; notify the Monster Manager');
- end;
- end;
-
-
- procedure niceprint(var len: integer; s: string);
-
- begin
- if len + length(s) > 78 then begin
- len := 0;
- writeln;
- end else begin
- len := len + length(s);
- end;
- write(s);
- end;
-
-
- procedure people_header(where: shortstring);
- var
- point: integer;
- tmp: string;
- i: integer;
- n: integer;
- len: integer;
-
- begin
- point := 1;
- n := n_can_see;
- case n of
- 0:;
- 1: begin
- writeln(next_can_see(point),' is ',where);
- end;
- 2: begin
- writeln(next_can_see(point),' and ',next_can_see(point),
- ' are ',where);
- end;
- otherwise begin
- len := 0;
- for i := 1 to n - 1 do begin { at least 1 to 2 }
- tmp := next_can_see(point);
- if i <> n - 1 then
- tmp := tmp + ', ';
- niceprint(len,tmp);
- end;
-
- niceprint(len,' and ');
- niceprint(len,next_can_see(point));
- niceprint(len,' are ' + where);
- writeln;
- end;
- end;
- end;
-
-
- procedure desc_person(i: integer);
- var
- pname: shortstring;
-
- begin
- pname := here.people[i].name;
-
- if here.people[i].act <> 0 then begin
- write(pname,' is');
- writeln(desc_action(here.people[i].act,
- here.people[i].targ));
- { describes what person last did }
- end;
-
- if here.people[i].health <> GOODHEALTH then
- desc_health(i);
-
- if here.people[i].wielding > 0 then
- writeln(pname,' is wielding ',obj_part(here.people[i].wielding),'.');
-
- end;
-
-
- procedure show_people;
- var
- i: integer;
-
- begin
- people_header('here.');
- for i := 1 to maxpeople do begin
- if (here.people[i].name <> '') and
- (i <> myslot) and
- (here.people[i].hiding = 0) then
- desc_person(i);
- end;
- end;
-
-
- procedure show_group;
- var
- gloc1,gloc2: integer;
- gnam1,gnam2: shortstring;
-
- begin
- gloc1 := here.grploc1;
- gloc2 := here.grploc2;
- gnam1 := here.grpnam1;
- gnam2 := here.grpnam2;
-
- if gloc1 <> 0 then begin
- gethere(gloc1);
- people_header(gnam1);
- end;
- if gloc2 <> 0 then begin
- gethere(gloc2);
- people_header(gnam2);
- end;
- gethere;
- end;
-
-
- procedure desc_obj(n: integer);
-
- begin
- if n <> 0 then begin
- getobj(n);
- freeobj;
- if (obj.linedesc = DEFAULT_LINE) then begin
- writeln('On the ground here is ',obj_part(n,FALSE),'.');
-
- { the FALSE means obj_part shouldn't do its
- own getobj, cause we already did one }
- end else
- print_line(obj.linedesc);
- end;
- end;
-
-
- procedure show_objects;
-
- var
- i: integer;
-
- begin
- for i := 1 to maxobjs do begin
- if (here.objs[i] <> 0) and (here.objhide[i] = 0) then
- desc_obj(here.objs[i]);
- end;
- end;
-
-
- function lookup_detail(var n: integer;s:string): boolean;
- var
- i,poss,maybe,num: integer;
-
- begin
- n := 0;
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to maxdetail do begin
- if s = here.detail[i] then
- num := i
- else if index(here.detail[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- n := num;
- lookup_detail := true;
- end else if maybe = 1 then begin
- n := poss;
- lookup_detail := true;
- end else if maybe > 1 then begin
- lookup_detail := false;
- end else begin
- lookup_detail := false;
- end;
- end;
-
-
- function look_detail(s: string): boolean;
- var
- n: integer;
-
- begin
- if lookup_detail(n,s) then begin
- if here.detaildesc[n] = 0 then
- look_detail := false
- else begin
- print_desc(here.detaildesc[n]);
- log_event(myslot,E_LOOKDETAIL,0,0,here.detail[n]);
- look_detail := true;
- end;
- end else
- look_detail := false;
- end;
-
-
- function look_person(s: string): boolean;
- var
- objnum,i,n: integer;
- first: boolean;
-
- begin
- if parse_pers(n,s) then begin
- if n = myslot then begin
- log_event(myslot,E_LOOKSELF,n,0);
- writeln('You step outside of yourself for a moment to get an objective self-appraisal:');
- writeln;
- end else
- log_event(myslot,E_LOOKYOU,n,0);
- if here.people[n].self <> 0 then begin
- print_desc(here.people[n].self);
- writeln;
- end;
-
- desc_health(n);
-
- { Do an inventory of person S }
- first := true;
- for i := 1 to maxhold do begin
- objnum := here.people[n].holding[i];
- if objnum <> 0 then begin
- if first then begin
- writeln(here.people[n].name,' is holding:');
- first := false;
- end;
- writeln(' ',obj_part(objnum));
- end;
- end;
- if first then
- writeln(here.people[n].name,' is empty handed.');
-
- look_person := true;
- end else
- look_person := false;
- end;
-
-
-
- procedure do_examine(s: string;var three: boolean;silent:boolean := false);
- var
- n: integer;
- msg: string;
-
- begin
- three := false;
- if parse_obj(n,s) then begin
- if obj_here(n) or obj_hold(n) then begin
- three := true;
-
- getobj(n);
- freeobj;
- msg := myname + ' is examining ' + obj_part(n) + '.';
- log_event(myslot,E_EXAMINE,0,0,msg);
- if obj.examine = 0 then
- writeln('You see nothing special about the ',
- objnam.idents[n],'.')
- else
- print_desc(obj.examine);
- end else
- if not(silent) then
- writeln('That object cannot be seen here.');
- end else
- if not(silent) then
- writeln('That object cannot be seen here.');
- end;
-
-
-
- procedure print_room;
-
- begin
- case here.nameprint of
- 0:; { don't print name }
- 1: writeln('You''re in ',here.nicename);
- 2: writeln('You''re at ',here.nicename);
- end;
-
- if not(brief) then begin
- case here.which of
- 0: print_desc(here.primary);
- 1: print_desc(here.secondary);
- 2: begin
- print_desc(here.primary);
- print_desc(here.secondary);
- end;
- 3: begin
- print_desc(here.primary);
- if here.magicobj <> 0 then
- if obj_hold(here.magicobj) then
- print_desc(here.secondary);
- end;
- 4: begin
- if here.magicobj <> 0 then begin
- if obj_hold(here.magicobj) then
- print_desc(here.secondary)
- else
- print_desc(here.primary);
- end else
- print_desc(here.primary);
- end;
- end;
- writeln;
- end; { if not(brief) }
- end;
-
-
-
- procedure do_look(s: string := '');
- var
- n: integer;
- one,two,three: boolean;
-
- begin
- gethere;
- if s = '' then begin { do an ordinary top-level room look }
-
- if hiding then begin
- writeln('You can''t get a very good view of the details of the room from where');
- writeln('you are hiding.');
- noisehide(67);
- end else begin
- print_room;
- show_exits;
- end; { end of what you can't see when you're hiding }
- show_people;
- show_group;
- show_objects;
- end else begin { look at a detail in the room }
- one := look_detail(s);
- two := look_person(s);
- do_examine(s,three,TRUE);
- if not(one or two or three) then
- writeln('There isn''t anything here by that name to look at.');
- end;
- end;
-
-
- procedure init_exit(dir: integer);
-
- begin
- with here.exits[dir] do begin
- exitdesc := DEFAULT_LINE;
- fail := DEFAULT_LINE; { default descriptions }
- success := 0; { until they customize }
- comeout := DEFAULT_LINE;
- goin := DEFAULT_LINE;
- closed := DEFAULT_LINE;
-
- objreq := 0; { not a door (yet) }
- hidden := 0; { not hidden }
- reqalias := false; { don't require alias (i.e. can use
- direction of exit North, east, etc. }
- reqverb := false;
- autolook := true;
- alias := '';
- end;
- end;
-
-
-
- procedure remove_exit(dir: integer);
- var
- targroom,targslot: integer;
- hereacc,targacc: boolean;
-
- begin
- { Leave residual accepts if player is not the owner of
- the room that the exit he is deleting is in }
-
- getroom;
- targroom := here.exits[dir].toloc;
- targslot := here.exits[dir].slot;
- here.exits[dir].toloc := 0;
- init_exit(dir);
-
- if (here.owner = userid) or (privd) then
- hereacc := false
- else
- hereacc := true;
-
- if hereacc then
- here.exits[dir].kind := 5 { put an "accept" in its place }
- else
- here.exits[dir].kind := 0;
-
- putroom;
- log_event(myslot,E_DETACH,dir,0,myname,location);
-
- getroom(targroom);
- here.exits[targslot].toloc := 0;
-
- if (here.owner = userid) or (privd) then
- targacc := false
- else
- targacc := true;
-
- if targacc then
- here.exits[targslot].kind := 5 { put an "accept" in its place }
- else
- here.exits[targslot].kind := 0;
-
- putroom;
-
- if targroom <> location then
- log_event(0,E_DETACH,targslot,0,myname,targroom);
- writeln('Exit destroyed.');
- end;
-
-
- {
- User procedure to unlink a room
- }
- procedure do_unlink(s: string);
- var
- dir: integer;
-
- begin
- gethere;
- if checkhide then begin
- if lookup_dir(dir,s) then begin
- if can_alter(dir) then begin
- if here.exits[dir].toloc = 0 then
- writeln('There is no exit there to unlink.')
- else
- remove_exit(dir);
- end else
- writeln('You are not allowed to remove that exit.');
- end else
- writeln('To remove an exit, type UNLINK <direction of exit>.');
- end;
- end;
-
-
-
- function desc_allowed: boolean;
-
- begin
- if (here.owner = userid) or
- (privd) then
- desc_allowed := true
- else begin
- writeln('Sorry, you are not allowed to alter the descriptions in this room.');
- desc_allowed := false;
- end;
- end;
-
-
-
- function slead(s: string):string;
- var
- i: integer;
- going: boolean;
-
- begin
- if length(s) = 0 then
- slead := ''
- else begin
- i := 1;
- going := true;
- while going do begin
- if i > length(s) then
- going := false
- else if (s[i]=' ') or (s[i]=chr(9)) then
- i := i + 1
- else
- going := false;
- end;
-
- if i > length(s) then
- slead := ''
- else
- slead := substr(s,i,length(s)+1-i);
- end;
- end;
-
-
- function bite(var s: string): string;
- var
- i: integer;
-
- begin
- if length(s) = 0 then
- bite := ''
- else begin
- i := index(s,' ');
- if i = 0 then begin
- bite := s;
- s := '';
- end else begin
- bite := substr(s,1,i-1);
- s := slead(substr(s,i+1,length(s)-i));
- end;
- end;
- end;
-
- procedure edit_help;
-
- begin
- writeln;
- writeln('A Append text to end');
- writeln('C Check text for correct length with parameter substitution (#)');
- writeln('D # Delete line #');
- writeln('E Exit & save changes');
- writeln('I # Insert lines before line #');
- writeln('P Print out description');
- writeln('Q Quit: THROWS AWAY CHANGES');
- writeln('R # Replace text of line #');
- writeln('Z Zap all text');
- writeln('@ Throw away text & exit with the default description');
- writeln('? This list');
- writeln;
- end;
-
- procedure edit_replace(n: integer);
- var
- prompt: string;
- s: string;
-
- begin
- if (n > heredsc.desclen) or (n < 1) then
- writeln('-- Bad line number')
- else begin
- writev(prompt,n:2,': ');
- grab_line(prompt,s);
- if s <> '**' then
- heredsc.lines[n] := s;
- end;
- end;
-
- procedure edit_insert(n: integer);
- var
- i: integer;
-
- begin
- if heredsc.desclen = descmax then
- writeln('You have already used all ',descmax:1,' lines of text.')
- else if (n < 1) or (n > heredsc.desclen) then begin
- writeln('Invalid line #; valid lines are between 1 and ',heredsc.desclen:1);
- writeln('Use A (add) to add text to the end of your description.');
- end else begin
- for i := heredsc.desclen+1 downto n + 1 do
- heredsc.lines[i] := heredsc.lines[i-1];
- heredsc.desclen := heredsc.desclen + 1;
- heredsc.lines[n] := '';
- end;
- end;
-
- procedure edit_doinsert(n: integer);
- var
- s: string;
- prompt: string;
-
- begin
- if heredsc.desclen = descmax then
- writeln('You have already used all ',descmax:1,' lines of text.')
- else if (n < 1) or (n > heredsc.desclen) then begin
- writeln('Invalid line #; valid lines are between 1 and ',heredsc.desclen:1);
- writeln('Use A (add) to add text to the end of your description.');
- end else repeat
- writev(prompt,n:1,': ');
- grab_line(prompt,s);
- if s <> '**' then begin
- edit_insert(n); { put the blank line in }
- heredsc.lines[n] := s; { copy this line onto it }
- n := n + 1;
- end;
- until (heredsc.desclen = descmax) or (s = '**');
- end;
-
- procedure edit_show;
- var
- i: integer;
-
- begin
- writeln;
- if heredsc.desclen = 0 then
- writeln('[no text]')
- else begin
- i := 1;
- while i <= heredsc.desclen do begin
- writeln(i:2,': ',heredsc.lines[i]);
- i := i + 1;
- end;
- end;
- end;
-
- procedure edit_append;
- var
- prompt,s: string;
- stilladding: boolean;
-
- begin
- if heredsc.desclen = descmax then
- writeln('You have already used all ',descmax:1,' lines of text.')
- else begin
- stilladding := true;
- writeln('Enter text. Terminate with ** at the beginning of a line.');
- writeln('You have ',descmax:1,' lines maximum.');
- writeln;
- while (heredsc.desclen < descmax) and (stilladding) do begin
- writev(prompt,heredsc.desclen+1:2,': ');
- grab_line(prompt,s);
- if s = '**' then
- stilladding := false
- else begin
- heredsc.desclen := heredsc.desclen + 1;
- heredsc.lines[heredsc.desclen] := s;
- end;
- end;
- end;
- end;
-
- procedure edit_delete(n: integer);
- var
- i: integer;
-
- begin
- if heredsc.desclen = 0 then
- writeln('-- No lines to delete')
- else if (n > heredsc.desclen) or (n < 1) then
- writeln('-- Bad line number')
- else if (n = 1) and (heredsc.desclen = 1) then
- heredsc.desclen := 0
- else begin
- for i := n to heredsc.desclen-1 do
- heredsc.lines[i] := heredsc.lines[i + 1];
- heredsc.desclen := heredsc.desclen - 1;
- end;
- end;
-
-
- procedure check_subst;
- var
- i: integer;
-
- begin
- if heredsc.desclen > 0 then begin
- for i := 1 to heredsc.desclen do
- if (index(heredsc.lines[i],'#') > 0) and
- (length(heredsc.lines[i]) > 59) then
- writeln('Warning: line ',i:1,' is too long for correct parameter substitution.');
- end;
- end;
-
-
- function edit_desc(var dsc: integer):boolean;
- var
- cmd: char;
- s: string;
- done: boolean;
- n: integer;
-
- begin
- if dsc = DEFAULT_LINE then begin
- heredsc.desclen := 0;
- end else if dsc > 0 then begin
- getblock(dsc);
- freeblock;
- heredsc := block;
- end else if dsc < 0 then begin
- n := (- dsc);
- getline(n);
- freeline;
- heredsc.lines[1] := oneliner.theline;
- heredsc.desclen := 1;
- end else begin
- heredsc.desclen := 0;
- end;
-
- edit_desc := true;
- done := false;
- if heredsc.desclen = 0 then
- edit_append;
- repeat
- writeln;
- repeat
- grab_line('* ',s);
- s := slead(s);
- until length(s) > 0;
- s := lowcase(s);
- cmd := s[1];
-
- if length(s)>1 then begin
- n := number(slead(substr(s,2,length(s)-1)))
- end else
- n := 0;
-
- case cmd of
- 'h','?': edit_help;
- 'a': edit_append;
- 'z': heredsc.desclen := 0;
- 'c': check_subst;
- 'p','l','t': edit_show;
- 'd': edit_delete(n);
- 'e': begin
- check_subst;
- if debug then
- writeln('edit_desc: dsc is ',dsc:1);
-
-
- { what I do here may require some explanation:
-
- dsc is a pointer to some text structure:
- dsc = 0 : no text
- dsc > 0 : dsc refers to a description block (descmax lines)
- dsc < 0 : dsc refers to a description "one liner". abs(dsc)
- is the actual pointer
-
- If there are no lines of text to be written out (heredsc.desclen = 0)
- then we deallocate whatever dsc is when edit_desc was invoked, if
- it was pointing to something;
-
- if there is one line of text to be written out, allocate a one liner
- record, assign the string to it, and return dsc as negative;
-
- if there is mmore than one line of text, allocate a description block,
- store the lines in it, and return dsc as positive.
-
- In all cases if there was already a record allocated to dsc then
- use it and don't reallocate a new record.
- }
-
- { kill the default } if (heredsc.desclen > 0) and
- { if we're gonna put real } (dsc = DEFAULT_LINE) then
- { texty in here } dsc := 0;
-
- { no lines, delete existing } if heredsc.desclen = 0 then
- { desc, if any } delete_block(dsc)
- else if heredsc.desclen = 1 then begin
- if (dsc = 0) then begin
- if alloc_line(dsc) then;
- dsc := (- dsc);
- end else if dsc > 0 then begin
- delete_block(dsc);
- if alloc_line(dsc) then;
- dsc := (- dsc);
- end;
-
- if dsc < 0 then begin
- getline( abs(dsc) );
- oneliner.theline := heredsc.lines[1];
- putline;
- end;
- { more than 1 lines } end else begin
- if dsc = 0 then begin
- if alloc_block(dsc) then;
- end else if dsc < 0 then begin
- delete_line(dsc);
- if alloc_block(dsc) then;
- end;
-
- if dsc > 0 then begin
- getblock(dsc);
- block := heredsc;
- { This is a fudge } block.descrinum := dsc;
- putblock;
- end;
- end;
- done := true;
- end;
- 'r': edit_replace(n);
- '@': begin
- delete_block(dsc);
- dsc := DEFAULT_LINE;
- done := true;
- end;
- 'i': edit_doinsert(n);
- 'q': begin
- grab_line('Throw away changes, are you sure? ',s);
- s := lowcase(s);
- if (s = 'y') or (s = 'yes') then begin
- done := true;
- edit_desc := false; { signal caller not to save }
- end;
- end;
- otherwise writeln('-- Invalid command, type ? for a list.');
- end;
- until done;
- end;
-
-
-
-
- function alloc_detail(var n: integer;s: string): boolean;
- var
- found: boolean;
-
- begin
- n := 1;
- found := false;
- while (n <= maxdetail) and (not found) do begin
- if here.detaildesc[n] = 0 then
- found := true
- else
- n := n + 1;
- end;
- alloc_detail := found;
- if not(found) then
- n := 0
- else begin
- getroom;
- here.detail[n] := lowcase(s);
- putroom;
- end;
- end;
-
-
- {
- User describe procedure. If no s then describe the room
-
- Known problem: if two people edit the description to the same room one of their
- description blocks could be lost.
- This is unlikely to happen unless the Monster Manager tries to edit a
- description while the room's owner is also editing it.
- }
- procedure do_describe(s: string);
- var
- i: integer;
- newdsc: integer;
-
- begin
- gethere;
- if checkhide then begin
- if s = '' then begin { describe this room }
- if desc_allowed then begin
- log_action(desc,0);
- writeln('[ Editing the primary room description ]');
- newdsc := here.primary;
- if edit_desc(newdsc) then begin
- getroom;
- here.primary := newdsc;
- putroom;
- end;
- log_event(myslot,E_EDITDONE,0,0);
- end;
- end else begin{ describe a detail of this room }
- if length(s) > veryshortlen then
- writeln('Your detail keyword can only be ',veryshortlen:1,' characters.')
- else if desc_allowed then begin
- if not(lookup_detail(i,s)) then
- if not(alloc_detail(i,s)) then begin
- writeln('You have used all ',maxdetail:1,' details.');
- writeln('To delete a detail, DESCRIBE <the detail> and delete all the text.');
- end;
- if i <> 0 then begin
- log_action(e_detail,0);
- writeln('[ Editing detail "',here.detail[i],'" of this room ]');
- newdsc := here.detaildesc[i];
- if edit_desc(newdsc) then begin
- getroom;
- here.detaildesc[i] := newdsc;
- putroom;
- end;
- log_event(myslot,E_DONEDET,0,0);
- end;
- end;
- end;
- { clear_command; }
- end;
- end;
-
-
-
-
- procedure del_room(n: integer);
- var
- i: integer;
-
- begin
- getnam;
- nam.idents[n] := ''; { blank out name }
- putnam;
-
- getown;
- own.idents[n] := ''; { blank out owner }
- putown;
-
- getroom(n);
- for i := 1 to maxexit do begin
- with here.exits[i] do begin
- delete_line(exitdesc);
- delete_line(fail);
- delete_line(success);
- delete_line(comeout);
- delete_line(goin);
- end;
- end;
- delete_block(here.primary);
- delete_block(here.secondary);
- putroom;
- delete_room(n); { return room to free list }
- end;
-
-
-
- procedure createroom(s: string); { create a room with name s }
- var
- roomno: integer;
- dummy: integer;
- i:integer;
- rand_accept: integer;
-
- begin
- if length(s) = 0 then begin
- writeln('Please specify the name of the room you wish to create as a parameter to FORM.');
- end else if length(s) > shortlen then begin
- writeln('Please limit your room name to a maximum of ',shortlen:1,' characters.');
- end else if exact_room(dummy,s) then begin
- writeln('That room name has already been used. Please give a unique room name.');
- end else if alloc_room(roomno) then begin
- log_action(form,0);
-
- getnam;
- nam.idents[roomno] := lowcase(s); { assign room name }
- putnam; { case insensitivity }
-
- getown;
- own.idents[roomno] := userid; { assign room owner }
- putown;
-
- getroom(roomno);
-
- here.primary := 0;
- here.secondary := 0;
- here.which := 0; { print primary desc only by default }
- here.magicobj := 0;
-
- here.owner := userid; { owner and name are stored here too }
- here.nicename := s;
- here.nameprint := 1; { You're in ... }
- here.objdrop := 0; { objects dropped stay here }
- here.objdesc := 0; { nothing printed when they drop }
- here.magicobj := 0; { no magic object default }
- here.trapto := 0; { no trapdoor }
- here.trapchance := 0; { no chance }
- here.rndmsg := DEFAULT_LINE; { bland noises message }
- here.pile := 0;
- here.grploc1 := 0;
- here.grploc2 := 0;
- here.grpnam1 := '';
- here.grpnam2 := '';
-
- here.effects := 0;
- here.parm := 0;
-
- here.xmsg2 := 0;
- here.exp2 := 0;
- here.exp3 := 0;
- here.exp4 := 0;
- here.exitfail := DEFAULT_LINE;
- here.ofail := DEFAULT_LINE;
-
- for i := 1 to maxpeople do
- here.people[i].kind := 0;
-
- for i := 1 to maxpeople do
- here.people[i].name := '';
-
- for i := 1 to maxobjs do
- here.objs[i] := 0;
-
- for i := 1 to maxdetail do
- here.detail[i] := '';
- for i := 1 to maxdetail do
- here.detaildesc[i] := 0;
-
- for i := 1 to maxobjs do
- here.objhide[i] := 0;
-
- for i := 1 to maxexit do
- with here.exits[i] do begin
- toloc := 0;
- kind := 0;
- slot := 0;
- exitdesc := DEFAULT_LINE;
- fail := DEFAULT_LINE;
- success := 0; { no success desc by default }
- goin := DEFAULT_LINE;
- comeout := DEFAULT_LINE;
- closed := DEFAULT_LINE;
-
- objreq := 0;
- hidden := 0;
- alias := '';
-
- reqverb := false;
- reqalias := false;
- autolook := true;
- end;
-
- { here.exits := zero; }
-
- { random accept for this room }
- rand_accept := 1 + (rnd100 mod 6);
- here.exits[rand_accept].kind := 5;
-
- putroom;
- end;
- end;
-
-
-
- procedure show_help;
- var
- i: integer;
- s: string;
-
- begin
- writeln;
- writeln('Accept/Refuse # Allow others to Link an exit here at direction # | Undo Accept');
- writeln('Brief Toggle printing of room descriptions');
- writeln('Customize [#] Customize this room | Customize exit # | Customize object #');
- writeln('Describe [#] Describe this room | Describe a feature (#) in detail');
- writeln('Destroy # Destroy an instance of object # (you must be holding it)');
- writeln('Duplicate # Make a duplicate of an already-created object.');
- writeln('Form/Zap # Form a new room with name # | Destroy room named #');
- writeln('Get/Drop # Get/Drop an object');
- writeln('#,Go # Go towards # (Some: N/North S/South E/East W/West U/Up D/Down)');
- writeln('Health Show how healthy you are');
- writeln('Hide/Reveal [#] Hide/Reveal yoursef | Hide object (#)');
- writeln('I,Inventory See what you or someone else is carrying');
- writeln('Link/Unlink # Link/Unlink this room to/from another via exit at direction #');
- writeln('Look,L [#] Look here | Look at something or someone (#) closely');
- writeln('Make # Make a new object named #');
- writeln('Name # Set your game name to #');
- writeln('Players List people who have played Monster');
- writeln('Punch # Punch person #');
- writeln('Quit Leave the game');
- writeln('Relink Move an exit');
- writeln;
- grab_line('-more-',s);
- writeln;
- writeln('Rooms Show information about rooms you have made');
- writeln('Say, '' (quote) Say line of text following command to others in the room');
- writeln('Search Look around the room for anything hidden');
- writeln('Self # Edit a description of yourself | View #''s self-description');
- writeln('Show # Show option # (type SHOW ? for a list)');
- writeln('Unmake # Remove the form definition of object #');
- writeln('Use # Use object #');
- writeln('Wear # Wear the object #');
- writeln('Wield # Wield the weapon #; you must be holding it first');
- writeln('Whisper # Whisper something (prompted for) to person #');
- writeln('Who List of people playing Monster now');
- writeln('Whois # What is a player''s username');
- writeln('?,Help This list');
- writeln('. (period) Repeat last command');
- writeln;
- end;
-
-
- function lookup_cmd(s: string):integer;
- var
- i, { index for loop }
- poss, { a possible match -- only for partial matches }
- maybe, { number of possible matches we have: > 2 is ambig. }
- num { the definite match }
- : integer;
-
-
- begin
- s := lowcase(s);
- i := 1;
- maybe := 0;
- num := 0;
- for i := 1 to numcmds do begin
- if s = cmds[i] then
- num := i
- else if index(cmds[i],s) = 1 then begin
- maybe := maybe + 1;
- poss := i;
- end;
- end;
- if num <> 0 then begin
- lookup_cmd := num;
- end else if maybe = 1 then begin
- lookup_cmd := poss;
- end else if maybe > 1 then
- lookup_cmd := error { "Ambiguous" }
- else
- lookup_cmd := error; { "Command not found " }
- end;
-
-
- procedure addrooms(n: integer);
- var
- i: integer;
-
- begin
- getindex(I_ROOM);
- for i := indx.top+1 to indx.top+n do begin
- locate(roomfile,i);
- roomfile^.valid := i;
- roomfile^.locnum := i;
- roomfile^.primary := 0;
- roomfile^.secondary := 0;
- roomfile^.which := 0;
- put(roomfile);
- end;
- indx.top := indx.top + n;
- putindex;
- end;
-
-
-
- procedure addints(n: integer);
- var
- i: integer;
-
- begin
- getindex(I_INT);
- for i := indx.top+1 to indx.top+n do begin
- locate(intfile,i);
- intfile^.intnum := i;
- put(intfile);
- end;
- indx.top := indx.top + n;
- putindex;
- end;
-
-
-
- procedure addlines(n: integer);
- var
- i: integer;
-
- begin
- getindex(I_LINE);
- for i := indx.top+1 to indx.top+n do begin
- locate(linefile,i);
- linefile^.linenum := i;
- put(linefile);
- end;
- indx.top := indx.top + n;
- putindex;
- end;
-
- procedure addblocks(n: integer);
- var
- i: integer;
-
- begin
- getindex(I_BLOCK);
- for i := indx.top+1 to indx.top+n do begin
- locate(descfile,i);
- descfile^.descrinum := i;
- put(descfile);
- end;
- indx.top := indx.top + n;
- putindex;
- end;
-
-
- procedure addobjects(n: integer);
- var
- i: integer;
-
- begin
- getindex(I_OBJECT);
- for i := indx.top+1 to indx.top+n do begin
- locate(objfile,i);
- objfile^.objnum := i;
- put(objfile);
- end;
- indx.top := indx.top + n;
- putindex;
- end;
-
-
- procedure dist_list;
- var
- i,j: integer;
- f: text;
- where_they_are: intrec;
-
- begin
- writeln('Writing distribution list . . .');
- open(f,'monsters.dis',history := new);
- rewrite(f);
-
- getindex(I_PLAYER); { Rec of valid player log records }
- freeindex; { False if a valid player log }
-
- getuser; { Corresponding userids of players }
- freeuser;
-
- getpers; { Personal names of players }
- freepers;
-
- getdate; { date of last play }
- freedate;
-
- if privd then begin
- getint(N_LOCATION);
- freeint;
- where_they_are := anint;
-
- getnam;
- freenam;
- end;
-
- for i := 1 to maxplayers do begin
- if not(indx.free[i]) then begin
- write(f,user.idents[i]);
- for j := length(user.idents[i]) to 15 do
- write(f,' ');
- write(f,'! ',pers.idents[i]);
- for j := length(pers.idents[i]) to 21 do
- write(f,' ');
-
- write(f,adate.idents[i]);
- if length(adate.idents[i]) < 19 then
- for j := length(adate.idents[i]) to 18 do
- write(f,' ');
- if anint.int[i] <> 0 then
- write(f,' * ')
- else
- write(f,' ');
-
- if privd then begin
- write(f,nam.idents[ where_they_are.int[i] ]);
- end;
- writeln(f);
-
- end;
- end;
- writeln('Done.');
- end;
-
-
- procedure system_view;
- var
- used,free,total: integer;
-
- begin
- writeln;
- getindex(I_BLOCK);
- freeindex;
- used := indx.inuse;
- total := indx.top;
- free := total - used;
-
- writeln(' used free total');
- writeln('Block file ',used:5,' ',free:5,' ',total:5);
-
- getindex(I_LINE);
- freeindex;
- used := indx.inuse;
- total := indx.top;
- free := total - used;
- writeln('Line file ',used:5,' ',free:5,' ',total:5);
-
- getindex(I_ROOM);
- freeindex;
- used := indx.inuse;
- total := indx.top;
- free := total - used;
- writeln('Room file ',used:5,' ',free:5,' ',total:5);
-
- getindex(I_OBJECT);
- freeindex;
- used := indx.inuse;
- total := indx.top;
- free := total - used;
- writeln('Object file ',used:5,' ',free:5,' ',total:5);
-
- getindex(I_INT);
- freeindex;
- used := indx.inuse;
- total := indx.top;
- free := total - used;
- writeln('Integer file ',used:5,' ',free:5,' ',total:5);
-
- writeln;
- end;
-
-
- { remove a user from the log records (does not handle ownership) }
-
- procedure kill_user(s:string);
- var
- n: integer;
-
- begin
- if length(s) = 0 then
- writeln('No user specified')
- else begin
- if lookup_user(n,s) then begin
- getindex(I_ASLEEP);
- freeindex;
- if indx.free[n] then begin
- delete_log(n);
- writeln('Player deleted.');
- end else
- writeln('That person is playing now.');
- end else
- writeln('No such userid found in log information.');
- end;
- end;
-
-
- { disown everything a player owns }
-
- procedure disown_user(s:string);
- var
- n: integer;
- i: integer;
- tmp: string;
- theuser: string;
-
- begin
- if length(s) > 0 then begin
- if debug then
- writeln('calling lookup_user with ',s);
- if not lookup_user(n,s) then
- writeln('User not in log info, attempting to disown anyway.');
-
- theuser := user.idents[n];
-
- { first disown all their rooms }
-
- getown;
- freeown;
- for i := 1 to maxroom do
- if own.idents[i] = theuser then begin
- getown;
- own.idents[i] := '*';
- putown;
-
- getroom(i);
- tmp := here.nicename;
- here.owner := '*';
- putroom;
-
- writeln('Disowned room ',tmp);
- end;
- writeln;
-
- getobjown;
- freeobjown;
- getobjnam;
- freeobjnam;
- for i := 1 to maxroom do
- if objown.idents[i] = theuser then begin
- getobjown;
- objown.idents[i] := '*';
- putobjown;
-
- tmp := objnam.idents[i];
- writeln('Disowned object ',tmp);
- end;
- end else
- writeln('No user specified.');
- end;
-
- procedure move_asleep;
- var
- pname,rname:string; { player & room names }
- newroom,n: integer; { room number & player slot number }
-
- begin
- grab_line('Player name? ',pname);
- grab_line('Room name? ',rname);
- if lookup_user(n,pname) then begin
- if lookup_room(newroom,rname) then begin
- getindex(I_ASLEEP);
- freeindex;
- if indx.free[n] then begin
- getint(N_LOCATION);
- anint.int[n] := newroom;
- putint;
- writeln('Player moved.');
- end else
- writeln('That player is not asleep.');
- end else
- writeln('No such room found.');
- end else
- writeln('User not found.');
- end;
-
-
- procedure system_help;
-
- begin
- writeln;
- writeln('B Add description blocks');
- writeln('D Disown <user>');
- writeln('E Exit (same as quit)');
- writeln('I Add Integer records');
- writeln('K Kill <user>');
- writeln('L Add one liner records');
- writeln('M Move a player who is asleep (not playing now)');
- writeln('O Add object records');
- writeln('P Write a distribution list of players');
- writeln('Q Quit (same as exit)');
- writeln('R Add rooms');
- writeln('V View current sizes/usage');
- writeln('? This list');
- writeln;
- end;
-
-
- { *************** FIX_STUFF ******************** }
-
- procedure fix_stuff;
-
- begin
- end;
-
-
- procedure do_system(s: string);
- var
- prompt: string;
- done: boolean;
- cmd: char;
- n: integer;
- p: string;
-
- begin
- if privd then begin
- log_action(c_system,0);
- prompt := 'System> ';
- done := false;
- repeat
- repeat
- grab_line(prompt,s);
- s := slead(s);
- until length(s) > 0;
- s := lowcase(s);
- cmd := s[1];
-
- n := 0;
- p := '';
- if length(s) > 1 then begin
- p := slead( substr(s,2,length(s)-1) );
- n := number(p)
- end;
- if debug then begin
- writeln('p = ',p);
- end;
-
- case cmd of
- 'h','?': system_help;
- '1': fix_stuff;
- {remove a user} 'k': kill_user(p);
- {disown} 'd': disown_user(p);
- {dist list of players} 'p': dist_list;
- {move where user will wakeup} 'm': move_asleep;
- {add rooms} 'r': begin
- if n > 0 then begin
- addrooms(n);
- end else
- writeln('To add rooms, say R <# to add>');
- end;
- {add ints} 'i': begin
- if n > 0 then begin
- addints(n);
- end else
- writeln('To add integers, say I <# to add>');
- end;
- {add description blocks} 'b': begin
- if n > 0 then begin
- addblocks(n);
- end else
- writeln('To add description blocks, say B <# to add>');
- end;
- {add objects} 'o': begin
- if n > 0 then begin
- addobjects(n);
- end else
- writeln('To add object records, say O <# to add>');
- end;
- {add one-liners} 'l': begin
- if n > 0 then begin
- addlines(n);
- end else
- writeln('To add one liner records, say L <# to add>');
- end;
- {view current stats} 'v': begin
- system_view;
- end;
- {quit} 'q','e': done := true;
- otherwise writeln('-- bad command, type ? for a list.');
- end;
- until done;
- log_event(myslot,E_SYSDONE,0,0);
- end else
- writeln('Only the Monster Manger may enter system maintenance mode.');
- end;
-
-
- procedure do_version(s: string);
-
- begin
- writeln('Monster, a multiplayer adventure game where the players create the world');
- writeln('and make the rules.');
- writeln;
- writeln('Written by Rich Skrenta at Northwestern University, 1988.');
- end;
-
-
- procedure rebuild_system;
- var
- i,j: integer;
-
- begin
- writeln('Creating index file 1-6');
- for i := 1 to 7 do begin
- { 1 is blocklist
- 2 is linelist
- 3 is roomlist
- 4 is playeralloc
- 5 is player awake (playing game)
- 6 are objects
- 7 is intfile }
-
- locate(indexfile,i);
- for j := 1 to maxindex do
- indexfile^.free[j] := true;
- indexfile^.indexnum := i;
- indexfile^.top := 0; { none of each to start }
- indexfile^.inuse := 0;
- put(indexfile);
- end;
-
-
- writeln('Initializing roomfile with 10 rooms');
- addrooms(10);
-
- writeln('Initializing block file with 10 description blocks');
- addblocks(10);
-
- writeln('Initializing line file with 10 lines');
- addlines(10);
-
- writeln('Initializing object file with 10 objects');
- addobjects(10);
-
-
- writeln('Initializing namfile 1-8');
- for j := 1 to 8 do begin
- locate(namfile,j);
- namfile^.validate := j;
- namfile^.loctop := 0;
- for i := 1 to maxroom do begin
- namfile^.idents[i] := '';
- end;
- put(namfile);
- end;
-
- writeln('Initializing eventfile');
- for i := 1 to numevnts + 1 do begin
- locate(eventfile,i);
- eventfile^.validat := i;
- eventfile^.point := 1;
- put(eventfile);
- end;
-
- writeln('Initializing intfile');
- for i := 1 to 6 do begin
- locate(intfile,i);
- intfile^.intnum := i;
- put(intfile);
- end;
-
- getindex(I_INT);
- for i := 1 to 6 do
- indx.free[i] := false;
- indx.top := 6;
- indx.inuse := 6;
- putindex;
-
- { Player log records should have all their slots initially,
- they don't have to be allocated because they use namrec
- and intfile for their storage; they don't have their own
- file to allocate
- }
- getindex(I_PLAYER);
- indx.top := maxplayers;
- putindex;
- getindex(I_ASLEEP);
- indx.top := maxplayers;
- putindex;
-
- writeln('Creating the Great Hall');
- createroom('Great Hall');
- getroom(1);
- here.owner := '';
- putroom;
- getown;
- own.idents[1] := '';
- putown;
-
- writeln('Creating the Void');
- createroom('Void'); { loc 2 }
- writeln('Creating the Pit of Fire');
- createroom('Pit of Fire'); { loc 3 }
- { note that these are NOT public locations }
-
-
- writeln('Use the SYSTEM command to view and add capacity to the database');
- writeln;
- end;
-
-
- procedure special(s: string);
-
- begin
- if (s = 'rebuild') and (privd) then begin
- if REBUILD_OK then begin
- writeln('Do you really want to destroy the entire universe?');
- readln(s);
- if length(s) > 0 then
- if substr(lowcase(s),1,1) = 'y' then
- rebuild_system;
- end else
- writeln('REBUILD is disabled; you must recompile.');
- end else if s = 'version' then begin
- { Don't take this out please... }
- writeln('Monster, written by Rich Skrenta at Northwestern University, 1988.');
- end else if s = 'quit' then
- done := true;
- end;
-
-
- { put an object in this location
- if returns false, there were no more free object slots here:
- in other words, the room is too cluttered, and cannot hold any
- more objects
- }
- function place_obj(n: integer;silent:boolean := false): boolean;
- var
- found: boolean;
- i: integer;
-
- begin
- if here.objdrop = 0 then
- getroom
- else
- getroom(here.objdrop);
- i := 1;
- found := false;
- while (i <= maxobjs) and (not found) do begin
- if here.objs[i] = 0 then
- found := true
- else
- i := i + 1;
- end;
- place_obj := found;
- if found then begin
- here.objs[i] := n;
- here.objhide[i] := 0;
- putroom;
-
- gethere;
-
-
- { if it bounced somewhere else then tell them }
-
- if (here.objdrop <> 0) and (here.objdest <> 0) then
- log_event(0,E_BOUNCEDIN,here.objdest,n,'',here.objdrop);
-
-
- if not(silent) then begin
- if here.objdesc <> 0 then
- print_subs(here.objdesc,obj_part(n))
- else
- writeln('Dropped.');
- end;
- end else
- freeroom;
- end;
-
-
- { remove an object from this room }
- function take_obj(objnum,slot: integer): boolean;
-
- begin
- getroom;
- if here.objs[slot] = objnum then begin
- here.objs[slot] := 0;
- here.objhide[slot] := 0;
- take_obj := true;
- end else
- take_obj := false;
- putroom;
- end;
-
-
- function can_hold: boolean;
-
- begin
- if find_numhold < maxhold then
- can_hold := true
- else
- can_hold := false;
- end;
-
-
- function can_drop: boolean;
-
- begin
- if find_numobjs < maxobjs then
- can_drop := true
- else
- can_drop := false;
- end;
-
-
- function find_hold(objnum: integer;slot:integer := 0): integer;
- var
- i: integer;
-
- begin
- if slot = 0 then
- slot := myslot;
- i := 1;
- find_hold := 0;
- while i <= maxhold do begin
- if here.people[slot].holding[i] = objnum then
- find_hold := i;
- i := i + 1;
- end;
- end;
-
-
-
- { put object number n into the player's inventory; returns false if
- he's holding too many things to carry another }
-
- function hold_obj(n: integer): boolean;
- var
- found: boolean;
- i: integer;
-
- begin
- getroom;
- i := 1;
- found := false;
- while (i <= maxhold) and (not found) do begin
- if here.people[myslot].holding[i] = 0 then
- found := true
- else
- i := i + 1;
- end;
- hold_obj := found;
- if found then begin
- here.people[myslot].holding[i] := n;
- putroom;
-
- getobj(n);
- freeobj;
- hold_kind[i] := obj.kind;
- end else
- freeroom;
- end;
-
-
-
- { remove an object (hold) from the player record, given the slot that
- the object is being held in }
-
- procedure drop_obj(slot: integer;pslot: integer := 0);
-
- begin
- if pslot = 0 then
- pslot := myslot;
- getroom;
- here.people[pslot].holding[slot] := 0;
- putroom;
-
- hold_kind[slot] := 0;
- end;
-
-
-
- { maybe drop something I'm holding if I'm hit }
-
- procedure maybe_drop;
- var
- i: integer;
- objnum: integer;
- s: string;
-
- begin
- i := 1 + (rnd100 mod maxhold);
- objnum := here.people[myslot].holding[i];
-
- if (objnum <> 0) and (mywield <> objnum) and (mywear <> objnum) then begin
- { drop something }
-
- drop_obj(i);
- if place_obj(objnum,TRUE) then begin
- getobjnam;
- freeobjnam;
- writeln('The ',objnam.idents[objnum],' has slipped out of your hands.');
-
-
- s := objnam.idents[objnum];
- log_event(myslot,E_SLIPPED,0,0,s);
- end else
- writeln('%error in maybe_drop; unsuccessful place_obj; notify Monster Manager');
-
- end;
- end;
-
-
-
- { return TRUE if the player is allowed to program the object n
- if checkpub is true then obj_owner will return true if the object in
- question is public }
-
- function obj_owner(n: integer;checkpub: boolean := FALSE):boolean;
-
- begin
- getobjown;
- freeobjown;
- if (objown.idents[n] = userid) or (privd) then begin
- obj_owner := true;
- end else if (objown.idents[n] = '') and (checkpub) then begin
- obj_owner := true;
- end else begin
- obj_owner := false;
- end;
- end;
-
-
- procedure do_duplicate(s: string);
- var
- objnum: integer;
-
- begin
- if length(s) > 0 then begin
- if not is_owner(location,TRUE) then begin
- { only let them make things if they're on their home turf }
- writeln('You may only create objects when you are in one of your own rooms.');
- end else begin
- if lookup_obj(objnum,s) then begin
- if obj_owner(objnum,TRUE) then begin
- if not(place_obj(objnum,TRUE)) then
- { put the new object here }
- writeln('There isn''t enough room here to make that.')
- else begin
- { keep track of how many there } getobj(objnum);
- { are in existence } obj.numexist := obj.numexist + 1;
- putobj;
-
- log_event(myslot,E_MADEOBJ,0,0,
- myname + ' has created an object here.');
- writeln('Object created.');
- end;
- end else
- writeln('Power to create that object belongs to someone else.');
- end else
- writeln('There is no object by that name.');
- end;
- end else
- writeln('To duplicate an object, type DUPLICATE <object name>.');
- end;
-
-
- { make an object }
- procedure do_makeobj(s: string);
- var
- objnum: integer;
-
- begin
- gethere;
- if checkhide then begin
- if not is_owner(location,TRUE) then begin
- writeln('You may only create objects when you are in one of your own rooms.');
- end else if s <> '' then begin
- if length(s) > shortlen then
- writeln('Please limit your object names to ',shortlen:1,' characters.')
- else if exact_obj(objnum,s) then begin { object already exits }
- writeln('That object already exits. If you would like to make another copy of it,');
- writeln('use the DUPLICATE command.');
- end else begin
- if debug then
- writeln('%beggining to create object');
- if find_numobjs < maxobjs then begin
- if alloc_obj(objnum) then begin
- if debug then
- writeln('%alloc_obj successful');
- getobjnam;
- objnam.idents[objnum] := lowcase(s);
- putobjnam;
- if debug then
- writeln('%getobjnam completed');
- getobjown;
- objown.idents[objnum] := userid;
- putobjown;
- if debug then
- writeln('%getobjown completed');
-
- getobj(objnum);
- obj.onum := objnum;
- obj.oname := s; { name of object }
- obj.kind := 0; { bland object }
- obj.linedesc := DEFAULT_LINE;
- obj.actindx := 0;
- obj.examine := 0;
- obj.numexist := 1;
- obj.home := 0;
- obj.homedesc := 0;
-
- obj.sticky := false;
- obj.getobjreq := 0;
- obj.getfail := 0;
- obj.getsuccess := DEFAULT_LINE;
-
- obj.useobjreq := 0;
- obj.uselocreq := 0;
- obj.usefail := DEFAULT_LINE;
- obj.usesuccess := DEFAULT_LINE;
-
- obj.usealias := '';
- obj.reqalias := false;
- obj.reqverb := false;
-
- if s[1] in ['a','A','e','E','i','I','o','O','u','U'] then
- obj.particle := 2 { an }
- else
- obj.particle := 1; { a }
-
- obj.d1 := 0;
- obj.d2 := 0;
- obj.exp3 := 0;
- obj.exp4 := 0;
- obj.exp5 := DEFAULT_LINE;
- obj.exp6 := DEFAULT_LINE;
- putobj;
-
-
- if debug then
- writeln('putobj completed');
- end;
- { else: alloc_obj prints errors by itself }
- if not(place_obj(objnum,TRUE)) then
- { put the new object here }
- writeln('%error in makeobj - could not place object; notify the Monster Manager.')
- else begin
- log_event(myslot,E_MADEOBJ,0,0,
- myname + ' has created an object here.');
- writeln('Object created.');
- end;
-
- end else
- writeln('This place is too crowded to create any more objects. Try somewhere else.');
- end;
- end else
- writeln('To create an object, type MAKE <object name>.');
- end;
- end;
-
- { remove the type block for an object; all instances of the object must
- be destroyed first }
-
- procedure do_unmake(s: string);
- var
- n: integer;
- tmp: string;
-
- begin
- if not(is_owner(location,TRUE)) then
- writeln('You must be in one of your own rooms to UNMAKE an object.')
- else if lookup_obj(n,s) then begin
- tmp := obj_part(n);
- { this will do a getobj(n) for us }
-
- if obj.numexist = 0 then begin
- delete_obj(n);
-
- log_event(myslot,E_UNMAKE,0,0,tmp);
- writeln('Object removed.');
- end else
- writeln('You must DESTROY all instances of the object first.');
- end else
- writeln('There is no object here by that name.');
- end;
-
-
- { destroy a copy of an object }
-
- procedure do_destroy(s: string);
- var
- slot,n: integer;
-
- begin
- if length(s) = 0 then
- writeln('To destroy an object you own, type DESTROY <object>.')
- else if not is_owner(location,TRUE) then
- writeln('You must be in one of your own rooms to destroy an object.')
- else if parse_obj(n,s) then begin
- getobjown;
- freeobjown;
- if (objown.idents[n] <> userid) and (objown.idents[n] <> '') and
- (not privd) then
- writeln('You must be the owner of an object to destroy it.')
- else if obj_hold(n) then begin
- slot := find_hold(n);
- drop_obj(slot);
-
- log_event(myslot,E_DESTROY,0,0,
- myname + ' has destroyed ' + obj_part(n) + '.');
- writeln('Object destroyed.');
-
- getobj(n);
- obj.numexist := obj.numexist - 1;
- putobj;
- end else if obj_here(n) then begin
- slot := find_obj(n);
- if not take_obj(n,slot) then
- writeln('Someone picked it up before you could destroy it.')
- else begin
- log_event(myslot,E_DESTROY,0,0,
- myname + ' has destroyed ' + obj_part(n,FALSE) + '.');
- writeln('Object destroyed.');
-
- getobj(n);
- obj.numexist := obj.numexist - 1;
- putobj;
- end;
- end else
- writeln('Such a thing is not here.');
- end else
- writeln('No such thing can be seen here.');
- end;
-
-
- function links_possible: boolean;
- var
- i: integer;
-
- begin
- gethere;
- links_possible := false;
- if is_owner(location,TRUE) then
- links_possible := true
- else begin
- for i := 1 to maxexit do
- if (here.exits[i].toloc = 0) and (here.exits[i].kind = 5) then
- links_possible := true;
- end;
- end;
-
-
-
- { make a room }
- procedure do_form(s: string);
-
- begin
- gethere;
- if checkhide then begin
- if links_possible then begin
- if s = '' then begin
- grab_line('Room name: ',s);
- end;
- s := slead(s);
-
- createroom(s);
- end else begin
- writeln('You may not create any new exits here. Go to a place where you can create');
- writeln('an exit before FORMing a new room.');
- end;
- end;
- end;
-
-
- procedure xpoof; { loc: integer; forward }
- var
- targslot: integer;
-
- begin
- if put_token(loc,targslot,here.people[myslot].hiding) then begin
- if hiding then begin
- log_event(myslot,E_HPOOFOUT,0,0,myname,location);
- log_event(myslot,E_HPOOFIN,0,0,myname,loc);
- end else begin
- log_event(myslot,E_POOFOUT,0,0,myname,location);
- log_event(targslot,E_POOFIN,0,0,myname,loc);
- end;
-
- take_token(myslot,location);
- myslot := targslot;
- location := loc;
- setevent;
- do_look;
- end else
- writeln('There is a crackle of electricity, but the poof fails.');
- end;
-
-
- procedure do_poof(s: string);
- var
- n,loc: integer;
-
- begin
- if privd then begin
- gethere;
- if lookup_room(loc,s) then begin
- xpoof(loc);
- end else if parse_pers(n,s) then begin
- grab_line('What room? ',s);
- if lookup_room(loc,s) then begin
- log_event(myslot,E_POOFYOU,n,loc);
- writeln;
- writeln('You extend your arms, muster some energy, and ',here.people[n].name,' is');
- writeln('engulfed in a cloud of orange smoke.');
- writeln;
- end else
- writeln('There is no room named ',s,'.');
- end else
- writeln('There is no room named ',s,'.');
- end else
- writeln('Only the Monster Manager may poof.');
- end;
-
-
- procedure link_room(origdir,targdir,targroom: integer);
-
- begin
- { since exit creation involves the writing of two records,
- perhaps there should be a global lock around this code,
- such as a get to some obscure index field or something.
- I haven't put this in because I don't believe that if this
- routine fails it will seriously damage the database.
-
- Actually, the lock should be on the test (do_link) but that
- would be hard }
-
- getroom;
- with here.exits[origdir] do begin
- toloc := targroom;
- kind := 1; { type of exit, they can customize later }
- slot := targdir; { exit it comes out in in target room }
-
- init_exit(origdir);
- end;
- putroom;
-
- log_event(myslot,E_NEWEXIT,0,0,myname,location);
- if location <> targroom then
- log_event(0,E_NEWEXIT,0,0,myname,targroom);
-
- getroom(targroom);
- with here.exits[targdir] do begin
- toloc := location;
- kind := 1;
- slot := origdir;
-
- init_exit(targdir);
- end;
- putroom;
- writeln('Exit created. Use CUSTOM ',direct[origdir],' to customize your exit.');
- end;
-
-
- {
- User procedure to link a room
- }
- procedure do_link(s: string);
- var
- ok: boolean;
- orgexitnam,targnam,trgexitnam: string;
- targroom, { number of target room }
- targdir, { number of target exit direction }
- origdir: integer;{ number of exit direction here }
- firsttime: boolean;
-
- begin
-
- { gethere; ! done in links_possible }
-
- if links_possible then begin
- log_action(link,0);
- if checkhide then begin
- writeln('Hit return alone at any prompt to terminate exit creation.');
- writeln;
-
- if s = '' then
- firsttime := false
- else begin
- orgexitnam := bite(s);
- firsttime := true;
- end;
-
- repeat
- if not(firsttime) then
- grab_line('Direction of exit? ',orgexitnam)
- else
- firsttime := false;
-
- ok :=lookup_dir(origdir,orgexitnam);
- if ok then
- ok := can_make(origdir);
- until (orgexitnam = '') or ok;
-
- if ok then begin
- if s = '' then
- firsttime := false
- else begin
- targnam := s;
- firsttime := true;
- end;
-
- repeat
- if not(firsttime) then
- grab_line('Room to link to? ',targnam)
- else
- firsttime := false;
-
- ok := lookup_room(targroom,targnam);
- until (targnam = '') or ok;
- end;
-
- if ok then begin
- repeat
- writeln('Exit comes out in target room');
- grab_line('from what direction? ',trgexitnam);
- ok := lookup_dir(targdir,trgexitnam);
- if ok then
- ok := can_make(targdir,targroom);
- until (trgexitnam='') or ok;
- end;
-
- if ok then begin { actually create the exit }
- link_room(origdir,targdir,targroom);
- end;
- end;
- end else
- writeln('No links are possible here.');
- end;
-
-
- procedure relink_room(origdir,targdir,targroom: integer);
- var
- tmp: exit;
- copyslot,
- copyloc: integer;
-
- begin
- gethere;
- tmp := here.exits[origdir];
- copyloc := tmp.toloc;
- copyslot := tmp.slot;
-
- getroom(targroom);
- here.exits[targdir] := tmp;
- putroom;
-
- getroom(copyloc);
- here.exits[copyslot].toloc := targroom;
- here.exits[copyslot].slot := targdir;
- putroom;
-
- getroom;
- here.exits[origdir].toloc := 0;
- init_exit(origdir);
- putroom;
- end;
-
-
- procedure do_relink(s: string);
- var
- ok: boolean;
- orgexitnam,targnam,trgexitnam: string;
- targroom, { number of target room }
- targdir, { number of target exit direction }
- origdir: integer;{ number of exit direction here }
- firsttime: boolean;
-
- begin
- log_action(c_relink,0);
- gethere;
- if checkhide then begin
- writeln('Hit return alone at any prompt to terminate exit relinking.');
- writeln;
-
- if s = '' then
- firsttime := false
- else begin
- orgexitnam := bite(s);
- firsttime := true;
- end;
-
- repeat
- if not(firsttime) then
- grab_line('Direction of exit to relink? ',orgexitnam)
- else
- firsttime := false;
-
- ok :=lookup_dir(origdir,orgexitnam);
- if ok then
- ok := can_alter(origdir);
- until (orgexitnam = '') or ok;
-
- if ok then begin
- if s = '' then
- firsttime := false
- else begin
- targnam := s;
- firsttime := true;
- end;
-
- repeat
- if not(firsttime) then
- grab_line('Room to relink exit into? ',targnam)
- else
- firsttime := false;
-
- ok := lookup_room(targroom,targnam);
- until (targnam = '') or ok;
- end;
-
- if ok then begin
- repeat
- writeln('New exit comes out in target room');
- grab_line('from what direction? ',trgexitnam);
- ok := lookup_dir(targdir,trgexitnam);
- if ok then
- ok := can_make(targdir,targroom);
- until (trgexitnam='') or ok;
- end;
-
- if ok then begin { actually create the exit }
- relink_room(origdir,targdir,targroom);
- end;
- end;
- end;
-
-
- { print the room default no-go message if there is one;
- otherwise supply the generic "you can't go that way" }
-
- procedure default_fail;
-
- begin
- if (here.exitfail <> 0) and (here.exitfail <> DEFAULT_LINE) then
- print_desc(here.exitfail)
- else
- writeln('You can''t go that way.');
- end;
-
- procedure exit_fail(dir: integer);
- var
- tmp: string;
-
- begin
- if (dir < 1) or (dir > maxexit) then
- default_fail
- else if (here.exits[dir].fail = DEFAULT_LINE) then begin
- case here.exits[dir].kind of
- 5: writeln('There isn''t an exit there yet.');
- 6: writeln('You don''t have the power to go there.');
- otherwise default_fail;
- end;
- end else if here.exits[dir].fail <> 0 then
- block_subs(here.exits[dir].fail,myname);
-
-
- { now print the exit failure message for everyone else in the room:
- if they tried to go through a valid exit,
- and the exit has an other-person failure desc, then
- substitute that one & use;
-
- if there is a room default other-person failure desc, then
- print that;
-
- if they tried to go through a valid exit,
- and the exit has no required alias, then
- print default exit fail
- else
- print generic "didn't leave room" message
-
- cases:
- 1) valid/alias exit and specific fail message
- 2) valid/alias exit and blanket fail message
- 3) valid exit (no specific or blanket) "x fails to go [direct]"
- 4) alias exit and blanket fail
- 5) blanket fail
- 6) generic fail
- }
-
- if dir <> 0 then
- log_event(myslot,E_FAILGO,dir,0);
- end;
-
-
-
- procedure do_exit; { (exit_slot: integer)-- declared forward }
- var
- orig_slot,
- targ_slot,
- orig_room,
- enter_slot,
- targ_room: integer;
- doalook: boolean;
-
- begin
- if (exit_slot < 1) or (exit_slot > 6) then
- exit_fail(exit_slot)
- else if here.exits[exit_slot].toloc > 0 then begin
- block_subs(here.exits[exit_slot].success,myname);
-
- orig_slot := myslot;
- orig_room := location;
- targ_room := here.exits[exit_slot].toloc;
- enter_slot := here.exits[exit_slot].slot;
- doalook := here.exits[exit_slot].autolook;
-
- { optimization for exit that goes nowhere;
- why go nowhere? For special effects, we
- don't want it to take too much time,
- the logs are important because they force the
- exit descriptions, but actually moving the
- player is unnecessary }
-
- if orig_room = targ_room then begin
- log_exit(exit_slot,orig_room,orig_slot);
- log_entry(enter_slot,targ_room,orig_slot);
- { orig_slot in log_entry 'cause we're not
- really going anwhere }
- if doalook then
- do_look;
- end else begin
- take_token(orig_slot,orig_room);
- if not put_token(targ_room,targ_slot) then begin
- { no room in room! }
- { put them back! Quick! } if not put_token(orig_room,myslot) then begin
- writeln('%Oh no!');
- halt;
- end;
- end else begin
- log_exit(exit_slot,orig_room,orig_slot);
- log_entry(enter_slot,targ_room,targ_slot);
-
- myslot := targ_slot;
- location := targ_room;
- setevent;
-
- if doalook then
- do_look;
- end;
- end;
- end else
- exit_fail(exit_slot);
- end;
-
-
-
- function cycle_open: boolean;
- var
- ch: char;
- s: string;
-
- begin
- s := systime;
- ch := s[5];
- if ch in ['1','3','5','7','9'] then
- cycle_open := true
- else
- cycle_open := false;
- end;
-
-
- function which_dir(var dir:integer;s: string): boolean;
- var
- aliasdir, exitdir: integer;
- aliasmatch,exitmatch,
- aliasexact,exitexact: boolean;
- exitreq: boolean;
-
- begin
- s := lowcase(s);
- if lookup_alias(aliasdir,s) then
- aliasmatch := true
- else
- aliasmatch := false;
- if lookup_dir(exitdir,s) then
- exitmatch := true
- else
- exitmatch := false;
- if aliasmatch then begin
- if s = here.exits[aliasdir].alias then
- aliasexact := true
- else
- aliasexact := false;
- end else
- aliasexact := false;
- if exitmatch then begin
- if (s = direct[exitdir]) or (s = substr(direct[exitdir],1,1)) then
- exitexact := true
- else
- exitexact := false;
- end else
- exitexact := false;
- if exitmatch then
- exitreq := here.exits[exitdir].reqalias
- else
- exitreq := false;
-
- dir := 0;
- which_dir := true;
- if aliasexact and exitexact then
- dir := aliasdir
- else if aliasexact then
- dir := aliasdir
- else if exitexact and not exitreq then
- dir := exitdir
- else if aliasmatch then
- dir := aliasdir
- else if exitmatch and not exitreq then
- dir := exitdir
- else if exitmatch and exitreq then begin
- dir := exitdir;
- which_dir := false;
- end else begin
- which_dir := false;
- end;
- end;
-
-
- procedure exit_case(dir: integer);
-
- begin
- case here.exits[dir].kind of
- 0: exit_fail(dir);
- 1: do_exit(dir); { more checking goes here }
-
- 3: if obj_hold(here.exits[dir].objreq) then
- exit_fail(dir)
- else
- do_exit(dir);
- 4: if rnd100 < 34 then
- do_exit(dir)
- else
- exit_fail(dir);
-
- 2: begin
- if obj_hold(here.exits[dir].objreq) then
- do_exit(dir)
- else
- exit_fail(dir);
- end;
- 6: if obj_hold(here.exits[dir].objreq) then
- do_exit(dir)
- else
- exit_fail(dir);
- 7: if cycle_open then
- do_exit(dir)
- else
- exit_fail(dir);
- end;
- end;
-
- {
- Player wants to go to s
- Handle everthing, this is the top level procedure
-
- Check that he can go to s
- Put him through the exit ( in do_exit )
- Do a look for him ( in do_exit )
- }
- procedure do_go(s: string;verb:boolean := true);
- var
- dir: integer;
-
- begin
- gethere;
- if checkhide then begin
- if length(s) = 0 then
- writeln('You must give the direction you wish to travel.')
- else begin
- if which_dir(dir,s) then begin
- if (dir >= 1) and (dir <= maxexit) then begin
- if here.exits[dir].toloc = 0 then begin
- exit_fail(dir);
- end else begin
- exit_case(dir);
- end;
- end else
- exit_fail(dir);
- end else
- exit_fail(dir);
- end;
- end;
- end;
-
-
- procedure nice_say(var s: string);
-
- begin
- { capitalize the first letter of their sentence }
-
- if s[1] in ['a'..'z'] then
- s[1] := chr( ord('A') + (ord(s[1]) - ord('a')) );
-
- { put a period on the end of their sentence if
- they don't use any punctuation. }
-
- if s[length(s)] in ['a'..'z','A'..'Z'] then
- s := s + '.';
- end;
-
-
- procedure do_say(s:string);
-
- begin
- if length(s) > 0 then begin
-
- { if length(s) + length(myname) > 79 then begin
- s := substr(s,1,75-length(myname));
- writeln('Your message was truncated:');
- writeln('-- ',s);
- end; }
-
- nice_say(s);
- if hiding then
- log_event(myslot,E_HIDESAY,0,0,s)
- else
- log_event(myslot,E_SAY,0,0,s);
- end else
- writeln('To talk to others in the room, type SAY <message>.');
- end;
-
- procedure do_setname(s: string);
- var
- notice: string;
- ok: boolean;
- dummy: integer;
- sprime: string;
-
- begin
- gethere;
- if s <> '' then begin
- if length(s) <= shortlen then begin
- sprime := lowcase(s);
- if (sprime = 'monster manager') and (userid <> MM_userid) then begin
- writeln('Only the Monster Manager can have that personal name.');
- ok := false;
- end else if (sprime = 'vice manager') and (userid <> MVM_userid) then begin
- writeln('Only the Vice Manager can have that name.');
- ok := false;
- end else if (sprime = 'faust') and (userid <> FAUST_userid) then begin
- writeln('You are not Faust! You may not have that name.');
- ok := false;
- end else
- ok := true;
-
- if ok then
- if exact_pers(dummy,sprime) then begin
- if dummy = myslot then
- ok := true
- else begin
- writeln('Someone already has that name. Your personal name must be unique.');
- ok := false;
- end;
- end;
-
- if ok then begin
- myname := s;
- getroom;
- notice := here.people[myslot].name;
- here.people[myslot].name := s;
- putroom;
- notice := notice + ' is now known as ' + s;
-
- if not(hiding) then
- log_event(0,E_SETNAM,0,0,notice);
- { slot 0 means notify this player also }
-
- getpers; { note the new personal name in the logfile }
- pers.idents[mylog] := s; { don't lowcase it }
- putpers;
- end;
- end else
- writeln('Please limit your personal name to ',shortlen:1,' characters.');
- end else
- writeln('You are known to others as ',myname);
- end;
-
- function sysdate:string;
- var
- thedate: packed array[1..11] of char;
-
- begin
- date(thedate);
- sysdate := thedate;
- end;
-
-
- {
- 1234567890123456789012345678901234567890
- example display for alignment:
-
- Monster Status
- 19-MAR-1988 08:59pm
-
- }
-
- procedure do_who;
- var
- i,j: integer;
- ok: boolean;
- metaok: boolean;
- roomown: veryshortstring;
-
- begin
- log_event(myslot,E_WHO,0,(rnd100 mod 4));
-
- { we need just about everything to print this list:
- player alloc index, userids, personal names,
- room names, room owners, and the log record }
-
- getindex(I_ASLEEP); { Get index of people who are playing now }
- freeindex;
- getuser;
- freeuser;
- getpers;
- freepers;
- getnam;
- freenam;
- getown;
- freeown;
- getint(N_LOCATION); { get where they are }
- freeint;
- writeln(' Monster Status');
- writeln(' ',sysdate,' ',systime);
- writeln;
- writeln('Username Game Name Where');
-
- if (privd) { or has_kind(O_ALLSEEING) } then
- metaok := true
- else
- metaok := false;
-
- for i := 1 to indx.top do begin
- if not(indx.free[i]) then begin
- write(user.idents[i]);
- j := length(user.idents[i]);
- while j < 16 do begin
- write(' ');
- j := j + 1;
- end;
-
- write(pers.idents[i]);
- j := length(pers.idents[i]);
- while j <= 25 do begin
- write(' ');
- j := j + 1;
- end;
-
- if not(metaok) then begin
- roomown := own.idents[anint.int[i]];
-
- { if a person is in a public or disowned room, or
- if they are in the domain of the WHOer, then the player should know
- where they are }
-
- if (roomown = '') or (roomown = '*') or
- (roomown = userid) then
- ok := true
- else
- ok := false;
-
-
- { the player obviously knows where he is }
- if i = mylog then
- ok := true;
- end;
-
-
- if ok or metaok then begin
- writeln(nam.idents[anint.int[i]]);
- end else
- writeln('n/a');
- end;
- end;
- end;
-
- function own_trans(s: string): string;
-
- begin
- if s = '' then
- own_trans := '<public>'
- else if s = '*' then
- own_trans := '<disowned>'
- else
- own_trans := s;
- end;
-
-
- procedure list_rooms(s: shortstring);
- var
- first: boolean;
- i,j,posit: integer;
-
- begin
- first := true;
- posit := 0;
- for i := 1 to indx.top do begin
- if (not indx.free[i]) and (own.idents[i] = s) then begin
- if posit = 3 then begin
- posit := 1;
- writeln;
- end else
- posit := posit + 1;
- if first then begin
- first := false;
- writeln(own_trans(s),':');
- end;
- write(' ',nam.idents[i]);
- for j := length(nam.idents[i]) to 21 do
- write(' ');
- end;
- end;
- if posit <> 3 then
- writeln;
- if first then
- writeln('No rooms owned by ',own_trans(s))
- else
- writeln;
- end;
-
-
- procedure list_all_rooms;
- var
- i,j: integer;
- tmp: packed array[1..maxroom] of boolean;
-
- begin
- tmp := zero;
- list_rooms(''); { public rooms first }
- list_rooms('*'); { disowned rooms next }
- for i := 1 to indx.top do begin
- if not(indx.free[i]) and not(tmp[i]) and
- (own.idents[i] <> '') and (own.idents[i] <> '*') then begin
- list_rooms(own.idents[i]); { player rooms }
- for j := 1 to indx.top do
- if own.idents[j] = own.idents[i] then
- tmp[j] := TRUE;
- end;
- end;
- end;
-
- procedure do_rooms(s: string);
- var
- cmd: string;
- id: veryshortstring;
- listall: boolean;
-
- begin
- getnam;
- freenam;
- getown;
- freeown;
- getindex(I_ROOM);
- freeindex;
-
- listall := false;
- s := lowcase(s);
- cmd := bite(s);
- if cmd = '' then
- id := userid
- else if cmd = 'public' then
- id := ''
- else if cmd = 'disowned' then
- id := '*'
- else if cmd = '<public>' then
- id := ''
- else if cmd = '<disowned>' then
- id := '*'
- else if cmd = '*' then
- listall := true
- else if length(cmd) > veryshortlen then
- id := substr(cmd,1,veryshortlen)
- else
- id := cmd;
-
- if listall then begin
- if privd then
- list_all_rooms
- else
- writeln('You may not obtain a list of all the rooms.');
- end else begin
- if privd or (userid = id) or (id = '') or (id = '*') then
- list_rooms(id)
- else
- writeln('You may not list rooms that belong to another player.');
- end;
- end;
-
-
-
- procedure do_objects;
- var
- i: integer;
- total,public,disowned,private: integer;
-
- begin
- getobjnam;
- freeobjnam;
- getobjown;
- freeobjown;
- getindex(I_OBJECT);
- freeindex;
-
- total := 0;
- public := 0;
- disowned := 0;
- private := 0;
-
- writeln;
- for i := 1 to indx.top do begin
- if not(indx.free[i]) then begin
- total := total + 1;
- if objown.idents[i]='' then begin
- writeln(i:4,' ','<public>':12,' ',objnam.idents[i]);
- public := public + 1
- end else if objown.idents[i]='*' then begin
- writeln(i:4,' ','<disowned>':12,' ',objnam.idents[i]);
- disowned := disowned + 1
- end else begin
- private := private + 1;
-
- if (objown.idents[i] = userid) or
- (privd) then begin
- { >>>>>> } writeln(i:4,' ',objown.idents[i]:12,' ',objnam.idents[i]);
- end;
- end;
- end;
- end;
- writeln;
- writeln('Public: ',public:4);
- writeln('Disowned: ',disowned:4);
- writeln('Private: ',private:4);
- writeln(' ----');
- writeln('Total: ',total:4);
- end;
-
-
- procedure do_claim(s: string);
- var
- n: integer;
- ok: boolean;
- tmp: string;
-
- begin
- if length(s) = 0 then begin { claim this room }
- getroom;
- if (here.owner = '*') or (privd) then begin
- here.owner := userid;
- putroom;
- getown;
- own.idents[location] := userid;
- putown;
- log_event(myslot,E_CLAIM,0,0);
- writeln('You are now the owner of this room.');
- end else begin
- freeroom;
- if here.owner = '' then
- writeln('This is a public room. You may not claim it.')
- else
- writeln('This room has an owner.');
- end;
- end else if lookup_obj(n,s) then begin
- getobjown;
- freeobjown;
- if objown.idents[n] = '' then
- writeln('That is a public object. You may DUPLICATE it, but may not CLAIM it.')
- else if objown.idents[n] <> '*' then
- writeln('That object has an owner.')
- else begin
- getobj(n);
- freeobj;
- if obj.numexist = 0 then
- ok := true
- else begin
- if obj_hold(n) or obj_here(n) then
- ok := true
- else
- ok := false;
- end;
-
- if ok then begin
- getobjown;
- objown.idents[n] := userid;
- putobjown;
- tmp := obj.oname;
- log_event(myslot,E_OBJCLAIM,0,0,tmp);
- writeln('You are now the owner the ',tmp,'.');
- end else
- writeln('You must have one to claim it.');
- end;
- end else
- writeln('There is nothing here by that name to claim.');
- end;
-
- procedure do_disown(s: string);
- var
- n: integer;
- tmp: string;
-
- begin
- if length(s) = 0 then begin { claim this room }
- getroom;
- if (here.owner = userid) or (privd) then begin
- getroom;
- here.owner := '*';
- putroom;
- getown;
- own.idents[location] := '*';
- putown;
- log_event(myslot,E_DISOWN,0,0);
- writeln('You have disowned this room.');
- end else begin
- freeroom;
- writeln('You are not the owner of this room.');
- end;
- end else begin { disown an object }
- if lookup_obj(n,s) then begin
- getobj(n);
- freeobj;
- tmp := obj.oname;
-
- getobjown;
- if objown.idents[n] = userid then begin
- objown.idents[n] := '*';
- putobjown;
- log_event(myslot,E_OBJDISOWN,0,0,tmp);
- writeln('You are no longer the owner of the ',tmp,'.');
- end else begin
- freeobjown;
- writeln('You are not the owner of any such thing.');
- end;
- end else
- writeln('You are not the owner of any such thing.');
- end;
- end;
-
-
- procedure do_public(s: string);
- var
- ok: boolean;
- tmp: string;
- n: integer;
-
- begin
- if privd then begin
- if length(s) = 0 then begin
- getroom;
- here.owner := '';
- putroom;
- getown;
- own.idents[location] := '';
- putown;
- end else if lookup_obj(n,s) then begin
- getobjown;
- freeobjown;
- if objown.idents[n] = '' then
- writeln('That is already public.')
- else begin
- getobj(n);
- freeobj;
- if obj.numexist = 0 then
- ok := true
- else begin
- if obj_hold(n) or obj_here(n) then
- ok := true
- else
- ok := false;
- end;
-
- if ok then begin
- getobjown;
- objown.idents[n] := '';
- putobjown;
-
- tmp := obj.oname;
- log_event(myslot,E_OBJPUBLIC,0,0,tmp);
- writeln('The ',tmp,' is now public.');
- end else
- writeln('You must have one to claim it.');
- end;
- end else
- writeln('There is nothing here by that name to claim.');
- end else
- writeln('Only the Monster Manager may make things public.');
- end;
-
-
-
- { sum up the number of real exits in this room }
-
- function find_numexits: integer;
- var
- i: integer;
- sum: integer;
-
- begin
- sum := 0;
- for i := 1 to maxexit do
- if here.exits[i].toloc <> 0 then
- sum := sum + 1;
- find_numexits := sum;
- end;
-
-
-
- { clear all people who have played monster and quit in this location
- out of the room so that when they start up again they won't be here,
- because we are destroying this room }
-
- procedure clear_people(loc: integer);
- var
- i: integer;
-
- begin
- getint(N_LOCATION);
- for i := 1 to maxplayers do
- if anint.int[i] = loc then
- anint.int[i] := 1;
- putint;
- end;
-
-
- procedure do_zap(s: string);
- var
- loc: integer;
-
- begin
- gethere;
- if checkhide then begin
- if lookup_room(loc,s) then begin
- gethere(loc);
- if (here.owner = userid) or (privd) then begin
- clear_people(loc);
- if find_numpeople = 0 then begin
- if find_numexits = 0 then begin
- if find_numobjs = 0 then begin
- del_room(loc);
- writeln('Room deleted.');
- end else
- writeln('You must remove all of the objects from that room first.');
- end else
- writeln('You must delete all of the exits from that room first.');
- end else
- writeln('Sorry, you cannot destroy a room if people are still in it.');
- end else
- writeln('You are not the owner of that room.');
- end else
- writeln('There is no room named ',s,'.');
- end;
- end;
-
-
- function room_nameinuse(num: integer; newname: string): boolean;
- var
- dummy: integer;
-
- begin
- if exact_obj(dummy,newname) then begin
- if dummy = num then
- room_nameinuse := false
- else
- room_nameinuse := true;
- end else
- room_nameinuse := false;
- end;
-
-
-
- procedure do_rename;
- var
- dummy: integer;
- newname: string;
- s: string;
-
- begin
- gethere;
- writeln('This room is named ',here.nicename);
- writeln;
- grab_line('New name: ',newname);
- if (newname = '') or (newname = '**') then
- writeln('No changes.')
- else if length(newname) > shortlen then
- writeln('Please limit your room name to ',shortlen:1,' characters.')
- else if room_nameinuse(location,newname) then
- writeln(newname,' is not a unique room name.')
- else begin
- getroom;
- here.nicename := newname;
- putroom;
-
- getnam;
- nam.idents[location] := lowcase(newname);
- putnam;
- writeln('Room name updated.');
- end;
- end;
-
-
- function obj_nameinuse(objnum: integer; newname: string): boolean;
- var
- dummy: integer;
-
- begin
- if exact_obj(dummy,newname) then begin
- if dummy = objnum then
- obj_nameinuse := false
- else
- obj_nameinuse := true;
- end else
- obj_nameinuse := false;
- end;
-
-
- procedure do_objrename(objnum: integer);
- var
- newname: string;
- s: string;
-
- begin
- getobj(objnum);
- freeobj;
-
- writeln('This object is named ',obj.oname);
- writeln;
- grab_line('New name: ',newname);
- if (newname = '') or (newname = '**') then
- writeln('No changes.')
- else if length(newname) > shortlen then
- writeln('Please limit your object name to ',shortlen:1,' characters.')
- else if obj_nameinuse(objnum,newname) then
- writeln(newname,' is not a unique object name.')
- else begin
- getobj(objnum);
- obj.oname := newname;
- putobj;
-
- getobjnam;
- objnam.idents[objnum] := lowcase(newname);
- putobjnam;
- writeln('Object name updated.');
- end;
- end;
-
-
-
- procedure view_room;
- var
- s: string;
- i: integer;
-
- begin
- writeln;
- getnam;
- freenam;
- getobjnam;
- freeobjnam;
-
- with here do begin
- writeln('Room: ',nicename);
- case nameprint of
- 0: writeln('Room name not printed');
- 1: writeln('"You''re in" precedes room name');
- 2: writeln('"You''re at" precedes room name');
- otherwise writeln('Room name printing is damaged.');
- end;
-
- write('Room owner: ');
- if owner = '' then
- writeln('<public>')
- else if owner = '*' then
- writeln('<disowned>')
- else
- writeln(owner);
-
- if primary = 0 then
- writeln('There is no primary description')
- else
- writeln('There is a primary description');
-
- if secondary = 0 then
- writeln('There is no secondary description')
- else
- writeln('There is a secondary description');
-
- case which of
- 0: writeln('Only the primary description will print');
- 1: writeln('Only the secondary description will print');
- 2: writeln('Both the primary and secondary descriptions will print');
- 3: begin
- writeln('The primary description will print, followed by the seconary description');
- writeln('if the player is holding the magic object');
- end;
- 4: begin
- writeln('If the player is holding the magic object, the secondary description will print');
- writeln('Otherwise, the primary description will print');
- end;
- otherwise writeln('The way the room description prints is damaged');
- end;
-
- writeln;
- if magicobj = 0 then
- writeln('There is no magic object for this room')
- else
- writeln('The magic object for this room is the ',objnam.idents[magicobj],'.');
-
- if objdrop = 0 then
- writeln('Dropped objects remain here')
- else begin
- writeln('Dropped objects go to ',nam.idents[objdrop],'.');
- if objdesc = 0 then
- writeln('Dropped.')
- else
- print_line(objdesc);
- if objdest = 0 then
- writeln('Nothing is printed when object "bounces in" to target room')
- else
- print_line(objdest);
- end;
- writeln;
- if trapto = 0 then
- writeln('There is no trapdoor set')
- else
- writeln('The trapdoor sends players ',direct[trapto],
- ' with a chance factor of ',trapchance:1,'%');
-
- for i := 1 to maxdetail do begin
- if length(detail[i]) > 0 then begin
- write('Detail "',detail[i],'" ');
- if detaildesc[i] > 0 then
- writeln('has a description')
- else
- writeln('has no description');
- end;
- end;
- writeln;
- end;
- end;
-
-
- procedure room_help;
-
- begin
- writeln;
- writeln('D Alter the way the room description prints');
- writeln('N Change how the room Name prints');
- writeln('P Edit the Primary room description [the default one] (same as desc)');
- writeln('S Edit the Secondary room description');
- writeln('X Define a mystery message');
- writeln;
- writeln('G Set the location that a dropped object really Goes to');
- writeln('O Edit the object drop description (for drop effects)');
- writeln('B Edit the target room (G) "bounced in" description');
- writeln;
- writeln('T Set the direction that the Trapdoor goes to');
- writeln('C Set the Chance of the trapdoor functioning');
- writeln;
- writeln('M Define the magic object for this room');
- writeln('R Rename the room');
- writeln;
- writeln('V View settings on this room');
- writeln('E Exit (same as quit)');
- writeln('Q Quit (same as exit)');
- writeln('? This list');
- writeln;
- end;
-
-
-
- procedure custom_room;
- var
- done: boolean;
- prompt: string;
- n: integer;
- s: string;
- newdsc: integer;
- bool: boolean;
-
- begin
- log_action(e_custroom,0);
- writeln;
- writeln('Customizing this room');
- writeln('If you would rather be customizing an exit, type CUSTOM <direction of exit>');
- writeln('If you would rather be customizing an object, type CUSTOM <object name>');
- writeln;
- done := false;
- prompt := 'Custom> ';
-
- repeat
- repeat
- grab_line(prompt,s);
- s := slead(s);
- until length(s) > 0;
- s := lowcase(s);
- case s[1] of
-
- 'e','q': done := true;
- '?','h': room_help;
- 'r': do_rename;
- 'v': view_room;
- {dir trapdoor goes} 't': begin
- grab_line('What direction does the trapdoor exit through? ',s);
- if length(s) > 0 then begin
- if lookup_dir(n,s) then begin
- getroom;
- here.trapto := n;
- putroom;
- writeln('Room updated.');
- end else
- writeln('No such direction.');
- end else
- writeln('No changes.');
- end;
- {chance} 'c': begin
- writeln('Enter the chance that in any given minute the player will fall through');
- writeln('the trapdoor (0-100) :');
- writeln;
- grab_line('? ',s);
- if isnum(s) then begin
- n := number(s);
- if n in [0..100] then begin
- getroom;
- here.trapchance := n;
- putroom;
- end else
- writeln('Out of range.');
- end else
- writeln('No changes.');
- end;
- 's': begin
- newdsc := here.secondary;
- writeln('[ Editing the secondary room description ]');
- if edit_desc(newdsc) then begin
- getroom;
- here.secondary := newdsc;
- putroom;
- end;
- end;
- 'p': begin
- { same as desc } newdsc := here.primary;
- writeln('[ Editing the primary room description ]');
- if edit_desc(newdsc) then begin
- getroom;
- here.primary := newdsc;
- putroom;
- end;
- end;
- 'o': begin
- writeln('Enter the line that will be printed when someone drops an object here:');
- writeln('If dropped objects do not stay here, you may use a # for the object name.');
- writeln('Right now it says:');
- if here.objdesc = 0 then
- writeln('Dropped. [default]')
- else
- print_line(here.objdesc);
-
- n := here.objdesc;
- make_line(n);
- getroom;
- here.objdesc := n;
- putroom;
- end;
- 'x': begin
- writeln('Enter a line that will be randomly shown.');
- writeln('Right now it says:');
- if here.objdesc = 0 then
- writeln('[none defined]')
- else
- print_line(here.rndmsg);
-
- n := here.rndmsg;
- make_line(n);
- getroom;
- here.rndmsg := n;
- putroom;
- end;
- {bounced in desc} 'b': begin
- writeln('Enter the line that will be displayed in the room where an object really');
- writeln('goes when an object dropped here "bounces" there:');
- writeln('Place a # where the object name should go.');
- writeln;
- writeln('Right now it says:');
- if here.objdest = 0 then
- writeln('Something has bounced into the room.')
- else
- print_line(here.objdest);
-
- n := here.objdest;
- make_line(n);
- getroom;
- here.objdest := n;
- putroom;
- end;
- 'm': begin
- getobjnam;
- freeobjnam;
- if here.magicobj = 0 then
- writeln('There is currently no magic object for this room.')
- else
- writeln(objnam.idents[here.magicobj],
- ' is currently the magic object for this room.');
- writeln;
- grab_line('New magic object? ',s);
- if s = '' then
- writeln('No changes.')
- else if lookup_obj(n,s) then begin
- getroom;
- here.magicobj := n;
- putroom;
- writeln('Room updated.');
- end else
- writeln('No such object found.');
- end;
- 'g': begin
- getnam;
- freenam;
- if here.objdrop = 0 then
- writeln('Objects dropped fall here.')
- else
- writeln('Objects dropped fall in ',nam.idents[here.objdrop],'.');
- writeln;
- writeln('Enter * for [this room]:');
- grab_line('Room dropped objects go to? ',s);
- if s = '' then
- writeln('No changes.')
- else if s = '*' then begin
- getroom;
- here.objdrop := 0;
- putroom;
- writeln('Room updated.');
- end else if lookup_room(n,s) then begin
- getroom;
- here.objdrop := n;
- putroom;
- writeln('Room updated.');
- end else
- writeln('No such room found.');
- end;
- 'd': begin
- writeln('Print room descriptions how?');
- writeln;
- writeln('0) Print primary (main) description only [default]');
- writeln('1) Print only secondary description.');
- writeln('2) Print both primary and secondary descriptions togther.');
- writeln('3) Print primary description first; then print secondary description only if');
- writeln(' the player is holding the magic object for this room.');
- writeln('4) Print secondary if holding the magic obj; print primary otherwise');
- writeln;
- grab_line('? ',s);
- if isnum(s) then begin
- n := number(s);
- if n in [0..4] then begin
- getroom;
- here.which := n;
- putroom;
- writeln('Room updated.');
- end else
- writeln('Out of range.');
- end else
- writeln('No changes.');
-
- end;
- 'n': begin
- writeln('How would you like the room name to print?');
- writeln;
- writeln('0) No room name is shown');
- writeln('1) "You''re in ..."');
- writeln('2) "You''re at ..."');
- writeln;
- grab_line('? ',s);
- if isnum(s) then begin
- n := number(s);
- if n in [0..2] then begin
- getroom;
- here.nameprint := n;
- putroom;
- end else
- writeln('Out of range.');
- end else
- writeln('No changes.');
- end;
- otherwise writeln('Bad command, type ? for a list');
- end;
- until done;
- log_event(myslot,E_ROOMDONE,0,0);
- end;
-
- procedure analyze_exit(dir: integer);
- var
- s: string;
-
- begin
- writeln;
- getnam;
- freenam;
- getobjnam;
- freeobjnam;
- with here.exits[dir] do begin
- s := alias;
- if s = '' then
- s := '(no alias)'
- else
- s := '(alias ' + s + ')';
- if here.exits[dir].reqalias then
- s := s + ' (required)'
- else
- s := s + ' (not required)';
-
- if toloc <> 0 then
- writeln('The ',direct[dir],' exit ',s,' goes to ',nam.idents[toloc])
- else
- writeln('The ',direct[dir],' exit goes nowhere.');
- if hidden <> 0 then
- writeln('Concealed.');
- write('Exit type: ');
- case kind of
- 0: writeln('no exit.');
- 1: writeln('Open passage.');
- 2: writeln('Door, object required to pass.');
- 3: writeln('No passage if holding object.');
- 4: writeln('Randomly fails');
- 5: writeln('Potential exit.');
- 6: writeln('Only exists while holding the required object.');
- 7: writeln('Timed exit');
- end;
- if objreq = 0 then
- writeln('No required object.')
- else
- writeln('Required object is: ',objnam.idents[objreq]);
-
-
- writeln;
- if exitdesc = DEFAULT_LINE then
- exit_default(dir,kind)
- else
- print_line(exitdesc);
-
- if success = 0 then
- writeln('(no success message)')
- else
- print_desc(success);
-
- if fail = DEFAULT_LINE then begin
- if kind = 5 then
- writeln('There isn'' an exit there yet.')
- else
- writeln('You can''t go that way.');
- end else
- print_desc(fail);
-
- if comeout = DEFAULT_LINE then
- writeln('# has come into the room from: ',direct[dir])
- else
- print_desc(comeout);
- if goin = DEFAULT_LINE then
- writeln('# has gone ',direct[dir])
- else
- print_desc(goin);
-
- writeln;
- if autolook then
- writeln('LOOK automatically done after exit used')
- else
- writeln('LOOK supressed on exit use');
- if reqverb then
- writeln('The alias is required to be a verb for exit use')
- else
- writeln('The exit can be used with GO or as a verb');
- end;
- writeln;
- end;
-
- procedure custom_help;
-
- begin
- writeln;
- writeln('A Set an Alias for the exit');
- writeln('C Conceal an exit');
- writeln('D Edit the exit''s main Description');
- writeln('E EXIT custom (saves changes)');
- writeln('F Edit the exit''s failure line');
- writeln('I Edit the line that others see when a player goes Into an exit');
- writeln('K Set the object that is the Key to this exit');
- writeln('L Automatically look [default] / don''t look on exit');
- writeln('O Edit the line that people see when a player comes Out of an exit');
- writeln('Q QUIT Custom (saves changes)');
- writeln('R Require/don''t require alias for exit; ignore direction');
- writeln('S Edit the success line');
- writeln('T Alter Type of exit (passage, door, etc)');
- writeln('V View exit information');
- writeln('X Require/don''t require exit name to be a verb');
- writeln('? This list');
- writeln;
- end;
-
-
- procedure get_key(dir: integer);
- var
- s: string;
- n: integer;
-
- begin
- getobjnam;
- freeobjnam;
- if here.exits[dir].objreq = 0 then
- writeln('Currently there is no key set for this exit.')
- else
- writeln(objnam.idents[here.exits[dir].objreq],' is the current key for this exit.');
- writeln('Enter * for [no key]');
- writeln;
-
- grab_line('What object is the door key? ',s);
- if length(s) > 0 then begin
- if s = '*' then begin
- getroom;
- here.exits[dir].objreq := 0;
- putroom;
- writeln('Exit updated.');
- end else if lookup_obj(n,s) then begin
- getroom;
- here.exits[dir].objreq := n;
- putroom;
- writeln('Exit updated.');
- end else
- writeln('There is no object by that name.');
- end else
- writeln('No changes.');
- end;
-
-
- procedure do_custom(dirnam: string);
- var
- prompt: string;
- done : boolean;
- s: string;
- dir: integer;
- n: integer;
-
- begin
- gethere;
- if checkhide then begin
- if length(dirnam) = 0 then begin
- if is_owner(location,TRUE) then
- custom_room
- else begin
- writeln('You are not the owner of this room; you cannot customize it.');
- writeln('However, you may be able to customize some of the exits. To customize an');
- writeln('exit, type CUSTOM <direction of exit>');
- end;
- end else if lookup_dir(dir,dirnam) then begin
- if can_alter(dir) then begin
- log_action(c_custom,0);
-
- writeln('Customizing ',direct[dir],' exit');
- writeln('If you would rather be customizing this room, type CUSTOM with no arguments');
- writeln('If you would rather be customizing an object, type CUSTOM <object name>');
- writeln;
- writeln('Type ** for any line to leave it unchanged.');
- writeln('Type return for any line to select the default.');
- writeln;
- writev(prompt,'Custom ',direct[dir],'> ');
- done := false;
- repeat
- repeat
- grab_line(prompt,s);
- s := slead(s);
- until length(s) > 0;
- s := lowcase(s);
- case s[1] of
- '?','h': custom_help;
- 'q','e': done := true;
- 'k': get_key(dir);
- 'c': begin
- writeln('Type the description that a player will see when the exit is found.');
- writeln('Make no text for description to unconceal the exit.');
- writeln;
- writeln('[ Editing the "hidden exit found" description ]');
- n := here.exits[dir].hidden;
- if edit_desc(n) then begin
- getroom;
- here.exits[dir].hidden := n;
- putroom;
- end;
- end;
- {req alias} 'r': begin
- getroom;
- here.exits[dir].reqalias :=
- not(here.exits[dir].reqalias);
- putroom;
-
- if here.exits[dir].reqalias then
- writeln('The alias for this exit will be required to reference it.')
- else
- writeln('The alias will not be required to reference this exit.');
- end;
- {req verb} 'x': begin
- getroom;
- here.exits[dir].reqverb :=
- not(here.exits[dir].reqverb);
- putroom;
-
- if here.exits[dir].reqverb then
- writeln('The exit name will be required to be used as a verb to use the exit')
- else
- writeln('The exit name may be used with GO or as a verb to use the exit');
- end;
- {autolook} 'l': begin
- getroom;
- here.exits[dir].autolook :=
- not(here.exits[dir].autolook);
- putroom;
-
- if here.exits[dir].autolook then
- writeln('A LOOK will be done after the player travels through this exit.')
- else
- writeln('The automatic LOOK will not be done when a player uses this exit.');
- end;
- 'a': begin
- grab_line('Alternate name for the exit? ',s);
- if length(s) > veryshortlen then
- writeln('Your alias must be less than ',veryshortlen:1,' characters.')
- else begin
- getroom;
- here.exits[dir].alias := lowcase(s);
- putroom;
- end;
- end;
- 'v': analyze_exit(dir);
- 't': begin
- writeln;
- writeln('Select the type of your exit:');
- writeln;
- writeln('0) No exit');
- writeln('1) Open passage');
- writeln('2) Door (object required to pass)');
- writeln('3) No passage if holding key');
- if privd then
- writeln('4) exit randomly fails');
- writeln('6) Exit exists only when holding object');
- if privd then
- writeln('7) exit opens/closes invisibly every minute');
- writeln;
- grab_line('Which type? ',s);
- if isnum(s) then begin
- n := number(s);
- if n in [0..4,6..7] then begin
- getroom;
- here.exits[dir].kind := n;
- putroom;
- writeln('Exit type updated.');
- writeln;
- if n in [2,6] then
- get_key(dir);
- end else
- writeln('Bad exit type.');
- end else
- writeln('Exit type not changed.');
- end;
- 'f': begin
- writeln('The failure description will print if the player attempts to go through the');
- writeln('the exit but cannot for any reason.');
- writeln;
- writeln('[ Editing the exit failure description ]');
-
- n := here.exits[dir].fail;
- if edit_desc(n) then begin
- getroom;
- here.exits[dir].fail := n;
- putroom;
- end;
- end;
- 'i': begin
- writeln('Edit the description that other players see when someone goes into');
- writeln('the exit. Place a # where the player''s name should appear.');
- writeln;
- writeln('[ Editing the exit "go in" description ]');
- n := here.exits[dir].goin;
- if edit_desc(n) then begin
- getroom;
- here.exits[dir].goin := n;
- putroom;
- end;
- end;
- 'o': begin
- writeln('Edit the description that other players see when someone comes out of');
- writeln('the exit. Place a # where the player''s name should appear.');
- writeln;
- writeln('[ Editing the exit "come out of" description ]');
- n := here.exits[dir].comeout;
- if edit_desc(n) then begin
- getroom;
- here.exits[dir].comeout := n;
- putroom;
- end;
- end;
- { main exit desc } 'd': begin
- writeln('Enter a one line description of the exit.');
- writeln;
- n := here.exits[dir].exitdesc;
- make_line(n);
- getroom;
- here.exits[dir].exitdesc := n;
- putroom;
- end;
- 's': begin
- writeln('The success description will print when the player goes through the exit.');
- writeln;
- writeln('[ Editing the exit success description ]');
-
- n := here.exits[dir].success;
- if edit_desc(n) then begin
- getroom;
- here.exits[dir].success := n;
- putroom;
- end;
- end;
- otherwise writeln('-- Bad command, type ? for a list');
- end;
- until done;
-
-
- log_event(myslot,E_CUSTDONE,0,0);
- end else
- writeln('You are not allowed to alter that exit.');
- end else if lookup_obj(n,dirnam) then
- { if lookup_obj returns TRUE then dirnam is name of object to custom }
- do_program(dirnam) { customize the object }
- else begin
- writeln('To customize this room, type CUSTOM');
- writeln('To customize an exits, type CUSTOM <direction>');
- writeln('To customize an object, type CUSTOM <object name>');
- end;
- { clear_command; }
- end;
- end;
-
-
-
- procedure reveal_people(var three: boolean);
- var
- retry,i: integer;
-
- begin
- if debug then
- writeln('%revealing people');
- three := false;
- retry := 1;
-
- repeat
- retry := retry + 1;
- i := (rnd100 mod maxpeople) + 1;
- if (here.people[i].hiding > 0) and
- (i <> myslot) then begin
- three := true;
- writeln('You''ve found ',here.people[i].name,' hiding in the shadows!');
- log_event(myslot,E_FOUNDYOU,i,0);
- end;
- until (retry > 7) or three;
- end;
-
-
-
- procedure reveal_objects(var two: boolean);
- var
- tmp: string;
- i: integer;
-
- begin
- if debug then
- writeln('%revealing objects');
- two := false;
- for i := 1 to maxobjs do begin
- if here.objs[i] <> 0 then { if there is an object here }
- if (here.objhide[i] <> 0) then begin
- two := true;
-
- if here.objhide[i] = DEFAULT_LINE then
- writeln('You''ve found ',obj_part(here.objs[i]),'.')
- else begin
- print_desc(here.objhide[i]);
- delete_block(here.objhide[i]);
- end;
- end;
- end;
- end;
-
-
- procedure reveal_exits(var one: boolean);
- var
- retry,i: integer;
-
- begin
- if debug then
- writeln('%revealing exits');
- one := false;
- retry := 1;
-
- repeat
- retry := retry + 1;
- i := (rnd100 mod maxexit) + 1; { a random exit }
- if (here.exits[i].hidden <> 0) and (not found_exit[i]) then begin
- one := true;
- found_exit[i] := true; { mark exit as found }
-
- if here.exits[i].hidden = DEFAULT_LINE then begin
- if here.exits[i].alias = '' then
- writeln('You''ve found a hidden exit: ',direct[i],'.')
- else
- writeln('You''ve found a hidden exit: ',here.exits[i].alias,'.');
- end else
- print_desc(here.exits[i].hidden);
- end;
- until (retry > 4) or (one);
- end;
-
-
- procedure do_search(s: string);
- var
- chance: integer;
- found,dummy: boolean;
-
- begin
- if checkhide then begin
- chance := rnd100;
- found := false;
- dummy := false;
-
- if chance in [1..20] then
- reveal_objects(found)
- else if chance in [21..40] then
- reveal_exits(found)
- else if chance in [41..60] then
- reveal_people(dummy);
-
- if found then begin
- log_event(myslot,E_FOUND,0,0);
- end else if not(dummy) then begin
- log_event(myslot,E_SEARCH,0,0);
- writeln('You haven''t found anything.');
- end;
- end;
- end;
-
- procedure do_unhide(s: string);
-
- begin
- if s = '' then begin
- if hiding then begin
- hiding := false;
- log_event(myslot,E_UNHIDE,0,0);
- getroom;
- here.people[myslot].hiding := 0;
- putroom;
- writeln('You are no longer hiding.');
- end else
- writeln('You were not hiding.');
- end;
- end;
-
-
- procedure do_hide(s: string);
- var
- slot,n: integer;
- founddsc: integer;
- tmp: string;
-
- begin
- gethere;
- if s = '' then begin { hide yourself }
-
- { don't let them hide (or hide better) if people
- that they can see are in the room. Note that the
- use of n_can_see instead of find_numpeople will
- let them hide if other people are hidden in the
- room that they have not seen. The previously hidden
- people will see them hide }
-
- if n_can_see > 0 then begin
- if hiding then
- writeln('You can''t hide any better with people in the room.')
- else
- writeln('You can''t hide when people are watching you.');
- end else if (rnd100 > 25) then begin
- if here.people[myslot].hiding >= 4 then
- writeln('You''re pretty well hidden now. I don''t think you could be any less visible.')
- else begin
- getroom;
- here.people[myslot].hiding :=
- here.people[myslot].hiding + 1;
- putroom;
- if hiding then begin
- log_event(myslot,E_NOISES,rnd100,0);
- writeln('You''ve managed to hide yourself a little better.');
- end else begin
- log_event(myslot,E_IHID,0,0);
- writeln('You''ve hidden yourself from view.');
- hiding := true;
- end;
- end;
- end else begin { unsuccessful }
- if hiding then
- writeln('You could not find a better hiding place.')
- else
- writeln('You could not find a good hiding place.');
- end;
- end else begin { Hide an object }
- if parse_obj(n,s) then begin
- if obj_here(n) then begin
- writeln('Enter the description the player will see when the object is found:');
- writeln('(if no description is given a default will be supplied)');
- writeln;
- writeln('[ Editing the "object found" description ]');
- founddsc := 0;
- if edit_desc(founddsc) then ;
- if founddsc = 0 then
- founddsc := DEFAULT_LINE;
-
- getroom;
- slot := find_obj(n);
- here.objhide[slot] := founddsc;
- putroom;
-
- tmp := obj_part(n);
- log_event(myslot,E_HIDOBJ,0,0,tmp);
- writeln('You have hidden ',tmp,'.');
- end else if obj_hold(n) then begin
- writeln('You''ll have to put it down before it can be hidden.');
- end else
- writeln('I see no such object here.');
- end else
- writeln('I see no such object here.');
- end;
- end;
-
-
- procedure do_punch(s: string);
- var
- sock,n: integer;
-
- begin
- if s <> '' then begin
- if parse_pers(n,s) then begin
- if n = myslot then
- writeln('Self-abuse will not be tolerated in the Monster universe.')
- else if protected(n) then begin
- log_event(myslot,E_TRYPUNCH,n,0);
- writeln('A mystic shield of force prevents you from attacking.');
- end else if here.people[n].username = MM_userid then begin
- log_event(myslot,E_TRYPUNCH,n,0);
- writeln('You can''t punch the Monster Manager.');
- end else begin
- if hiding then begin
- hiding := false;
-
- getroom;
- here.people[myslot].hiding := 0;
- putroom;
-
- log_event(myslot,E_HIDEPUNCH,n,0);
- writeln('You pounce unexpectedly on ',here.people[n].name,'!');
- end else begin
- sock := (rnd100 mod numpunches)+1;
- log_event(myslot,E_PUNCH,n,sock);
- put_punch(sock,here.people[n].name);
- end;
- wait(1+random*3); { Ha ha ha }
- end;
- end else
- writeln('That person cannot be seen in this room.');
- end else
- writeln('To punch somebody, type PUNCH <personal name>.');
- end;
-
-
- { support for do_program (custom an object)
- Give the player a list of kinds of object he's allowed to make his object
- and update it }
-
- procedure prog_kind(objnum: integer);
- var
- n: integer;
- s: string;
-
- begin
- writeln('Select the type of your object:');
- writeln;
- writeln('0 Ordinary object (good for door keys)');
- writeln('1 Weapon');
- writeln('2 Armor');
- writeln('3 Exit thruster');
-
- if privd then begin
- writeln;
- writeln('100 Bag');
- writeln('101 Crystal Ball');
- writeln('102 Wand of Power');
- writeln('103 Hand of Glory');
- end;
- writeln;
- grab_line('Which kind? ',s);
-
- if isnum(s) then begin
- n := number(s);
- if (n > 100) and (privd) then
- writeln('Out of range.')
- else if n in [0..3,100..103] then begin
- getobj(objnum);
- obj.kind := n;
- putobj;
- writeln('Object updated.');
- end else
- writeln('Out of range.');
- end;
- end;
-
-
-
- { support for do_program (custom an object)
- Based on the kind it is allow the
- user to set the various parameters for the effects associated with that
- kind }
-
- procedure prog_obj(objnum: integer);
-
- begin
- end;
-
-
- procedure show_kind(p: integer);
-
- begin
- case p of
- 0: writeln('Ordinary object');
- 1: writeln('Weapon');
- 2: writeln('Armor');
- 100: writeln('Bag');
- 101: writeln('Crystal Ball');
- 102: writeln('Wand of Power');
- 103: writeln('Hand of Glory');
- otherwise writeln('Bad object type');
- end;
- end;
-
-
- procedure obj_view(objnum: integer);
-
- begin
- writeln;
- getobj(objnum);
- freeobj;
- getobjown;
- freeobjown;
- writeln('Object name: ',obj.oname);
- writeln('Owner: ',objown.idents[objnum]);
- writeln;
- show_kind(obj.kind);
- writeln;
-
- if obj.linedesc = 0 then
- writeln('There is a(n) # here')
- else
- print_line(obj.linedesc);
-
- if obj.examine = 0 then
- writeln('No inspection description set')
- else
- print_desc(obj.examine);
-
- { writeln('Worth (in points) of this object: ',obj.worth:1); }
- writeln('Number in existence: ',obj.numexist:1);
- writeln;
- end;
-
-
- procedure program_help;
-
- begin
- writeln;
- writeln('A "a", "an", "some", etc.');
- writeln('D Edit a Description of the object');
- writeln('F Edit the GET failure message');
- writeln('G Set the object required to pick up this object');
- writeln('1 Set the get success message');
- writeln('K Set the Kind of object this is');
- writeln('L Edit the label description ("There is a ... here.")');
- writeln('P Program the object based on the kind it is');
- writeln('R Rename the object');
- writeln('S Toggle the sticky bit');
- writeln;
- writeln('U Set the object required for use');
- writeln('2 Set the place required for use');
- writeln('3 Edit the use failure description');
- writeln('4 Edit the use success description');
- writeln('V View attributes of this object');
- writeln;
- writeln('X Edit the extra description');
- writeln('5 Edit extra desc #2');
- writeln('E Exit (same as Quit)');
- writeln('Q Quit (same as Exit)');
- writeln('? This list');
- writeln;
- end;
-
-
- procedure do_program; { (objnam: string); declared forward }
- var
- prompt: string;
- done : boolean;
- s: string;
- objnum: integer;
- n: integer;
- newdsc: integer;
-
- begin
- gethere;
- if checkhide then begin
- if length(objnam) = 0 then begin
- writeln('To program an object, type PROGRAM <object name>.');
- end else if lookup_obj(objnum,objnam) then begin
- if not is_owner(location,TRUE) then begin
- writeln('You may only work on your objects when you are in one of your own rooms.');
- end else if obj_owner(objnum) then begin
- log_action(e_program,0);
- writeln;
- writeln('Customizing object');
- writeln('If you would rather be customizing an EXIT, type CUSTOM <direction of exit>');
- writeln('If you would rather be customizing this room, type CUSTOM');
- writeln;
- getobj(objnum);
- freeobj;
- prompt := 'Custom object> ';
- done := false;
- repeat
- repeat
- grab_line(prompt,s);
- s := slead(s);
- until length(s) > 0;
- s := lowcase(s);
- case s[1] of
- '?','h': program_help;
- 'q','e': done := true;
- 'v': obj_view(objnum);
- 'r': do_objrename(objnum);
- 'g': begin
- writeln('Enter * for no object');
- grab_line('Object required for GET? ',s);
- if s = '*' then begin
- getobj(objnum);
- obj.getobjreq := 0;
- putobj;
- end else if lookup_obj(n,s) then begin
- getobj(objnum);
- obj.getobjreq := n;
- putobj;
- writeln('Object modified.');
- end else
- writeln('No such object.');
- end;
- 'u': begin
- writeln('Enter * for no object');
- grab_line('Object required for USE? ',s);
- if s = '*' then begin
- getobj(objnum);
- obj.useobjreq := 0;
- putobj;
- end else if lookup_obj(n,s) then begin
- getobj(objnum);
- obj.useobjreq := n;
- putobj;
- writeln('Object modified.');
- end else
- writeln('No such object.');
- end;
- '2': begin
- writeln('Enter * for no special place');
- grab_line('Place required for USE? ',s);
- if s = '*' then begin
- getobj(objnum);
- obj.uselocreq := 0;
- putobj;
- end else if lookup_room(n,s) then begin
- getobj(objnum);
- obj.uselocreq := n;
- putobj;
- writeln('Object modified.');
- end else
- writeln('No such object.');
- end;
- 's': begin
- getobj(objnum);
- obj.sticky := not(obj.sticky);
- putobj;
- if obj.sticky then
- writeln('The object will not be takeable.')
- else
- writeln('The object will be takeable.');
- end;
- 'a': begin
- writeln;
- writeln('Select the article for your object:');
- writeln;
- writeln('0) None ex: " You have taken Excalibur "');
- writeln('1) "a" ex: " You have taken a small box "');
- writeln('2) "an" ex: " You have taken an empty bottle "');
- writeln('3) "some" ex: " You have picked up some jelly beans "');
- writeln('4) "the" ex: " You have picked up the Scepter of Power"');
- writeln;
- grab_line('? ',s);
- if isnum(s) then begin
- n := number(s);
- if n in [0..4] then begin
- getobj(objnum);
- obj.particle := n;
- putobj;
- end else
- writeln('Out of range.');
- end else
- writeln('No changes.');
- end;
- 'k': begin
- prog_kind(objnum);
- end;
- 'p': begin
- prog_obj(objnum);
- end;
- 'd': begin
- newdsc := obj.examine;
- writeln('[ Editing the description of the object ]');
- if edit_desc(newdsc) then begin
- getobj(objnum);
- obj.examine := newdsc;
- putobj;
- end;
- end;
- 'x': begin
- newdsc := obj.d1;
- writeln('[ Editing extra description #1 ]');
- if edit_desc(newdsc) then begin
- getobj(objnum);
- obj.d1 := newdsc;
- putobj;
- end;
- end;
- '5': begin
- newdsc := obj.d2;
- writeln('[ Editing extra description #2 ]');
- if edit_desc(newdsc) then begin
- getobj(objnum);
- obj.d2 := newdsc;
- putobj;
- end;
- end;
- 'f': begin
- newdsc := obj.getfail;
- writeln('[ Editing the get failure description ]');
- if edit_desc(newdsc) then begin
- getobj(objnum);
- obj.getfail := newdsc;
- putobj;
- end;
- end;
- '1': begin
- newdsc := obj.getsuccess;
- writeln('[ Editing the get success description ]');
- if edit_desc(newdsc) then begin
- getobj(objnum);
- obj.getsuccess := newdsc;
- putobj;
- end;
- end;
- '3': begin
- newdsc := obj.usefail;
- writeln('[ Editing the use failure description ]');
- if edit_desc(newdsc) then begin
- getobj(objnum);
- obj.usefail := newdsc;
- putobj;
- end;
- end;
- '4': begin
- newdsc := obj.usesuccess;
- writeln('[ Editing the use success description ]');
- if edit_desc(newdsc) then begin
- getobj(objnum);
- obj.usesuccess := newdsc;
- putobj;
- end;
- end;
- 'l': begin
- writeln('Enter a one line description of what the object will look like in any room.');
- writeln('Example: "There is an as unyet described object here."');
- writeln;
- getobj(objnum);
- freeobj;
- n := obj.linedesc;
- make_line(n);
- getobj(objnum);
- obj.linedesc := n;
- putobj;
- end;
- otherwise writeln('-- Bad command, type ? for a list');
- end;
- until done;
- log_event(myslot,E_OBJDONE,objnum,0);
-
- end else
- writeln('You are not allowed to program that object.');
- end else
- writeln('There is no object by that name.');
- end;
- end;
-
-
- { returns TRUE if anything was actually dropped }
- function drop_everything;
- { forward function drop_everything(pslot: integer := 0): boolean; }
- var
- i: integer;
- slot: integer;
- didone: boolean;
- theobj: integer;
- tmp: string;
-
- begin
- if pslot = 0 then
- pslot := myslot;
-
- gethere;
- didone := false;
-
- mywield := 0;
- mywear := 0;
-
- for i := 1 to maxhold do begin
- if here.people[pslot].holding[i] <> 0 then begin
- didone := true;
- theobj := here.people[pslot].holding[i];
- slot := find_hold(theobj,pslot);
- if place_obj(theobj,TRUE) then begin
- drop_obj(slot,pslot);
- end else begin { no place to put it, it's lost .... }
- getobj(theobj);
- obj.numexist := obj.numexist - 1;
- putobj;
- tmp := obj.oname;
- writeln('The ',tmp,' was lost.');
- end;
- end;
- end;
-
- drop_everything := didone;
- end;
-
- procedure do_endplay(lognum: integer;ping:boolean := FALSE);
-
- { If update is true do_endplay will update the "last play" date & time
- we don't want to do this if this endplay is called from a ping }
-
- begin
- if not(ping) then begin
- { Set the "last date & time of play" }
- getdate;
- adate.idents[lognum] := sysdate + ' ' + systime;
- putdate;
- end;
-
-
- { Put the player to sleep. Don't delete his information,
- so it can be restored the next time they play. }
-
- getindex(I_ASLEEP);
- indx.free[lognum] := true; { Yes, I'm asleep }
- putindex;
- end;
-
-
- function check_person(n: integer;id: string):boolean;
-
- begin
- inmem := false;
- gethere;
- if here.people[n].username = id then
- check_person := true
- else
- check_person := false;
- end;
-
-
- function nuke_person(n: integer;id: string): boolean;
- var
- lognum: integer;
- tmp: string;
-
- begin
- getroom;
- if here.people[n].username = id then begin
-
- { drop everything they're carrying }
- drop_everything(n);
-
- tmp := here.people[n].username;
- { we'll need this for do_endplay }
-
- { Remove the person from the room }
- here.people[n].kind := 0;
- here.people[n].username := '';
- here.people[n].name := '';
- putroom;
-
- { update the log entries for them }
- { but first we have to find their log number
- (mylog for them). We can do this with a lookup_user
- give the userid we got above }
-
- if lookup_user(lognum,tmp) then begin
- do_endplay(lognum,TRUE);
- { TRUE tells do_endplay not to update the
- "time of last play" information 'cause we
- don't know how long the "zombie" has been
- there. }
- end else
- writeln('%error in nuke_person; can''t fing their log number; notify the Monster Manager');
-
- nuke_person := true;
- end else begin
- freeroom;
- nuke_person := false;
- end;
- end;
-
-
- function ping_player(n:integer;silent: boolean := false): boolean;
- var
- retry: integer;
- id: string;
- idname: string;
-
- begin
- ping_player := false;
-
- id := here.people[n].username;
- idname := here.people[n].name;
-
- retry := 0;
- ping_answered := false;
-
- repeat
- retry := retry + 1;
- if not(silent) then
- writeln('Sending ping # ',retry:1,' to ',idname,' . . .');
-
- log_event(myslot,E_PING,n,0,myname);
- wait(1);
- checkevents(TRUE);
- { TRUE = don't reprint prompt }
-
- if not(ping_answered) then
- if check_person(n,id) then begin
- wait(1);
- checkevents(TRUE);
- end else
- ping_answered := true;
-
- if not(ping_answered) then
- if check_person(n,id) then begin
- wait(1);
- checkevents(TRUE);
- end else
- ping_answered := true;
-
- until (retry >= 3) or ping_answered;
-
- if not(ping_answered) then begin
- if not(silent) then
- writeln('That person is not responding to your pings . . .');
-
- if nuke_person(n,id) then begin
- ping_player := true;
- if not(silent) then
- writeln(idname,' shimmers and vanishes from sight.');
- log_event(myslot,E_PINGONE,n,0,idname);
- end else
- if not(silent) then
- writeln('That person is not a zombie after all.');
- end else
- if not(silent) then
- writeln('That person is alive and well.');
- end;
-
-
- procedure do_ping(s: string);
- var
- n: integer;
- dummy: boolean;
-
- begin
- if s <> '' then begin
- if parse_pers(n,s) then begin
- if n = myslot then
- writeln('Don''t ping yourself.')
- else
- dummy := ping_player(n);
- end else
- writeln('You see no person here by that name.');
- end else
- writeln('To see if someone is really alive, type PING <personal name>.');
- end;
-
- procedure list_get;
- var
- first: boolean;
- i: integer;
-
- begin
- first := true;
- for i := 1 to maxobjs do begin
- if (here.objs[i] <> 0) and
- (here.objhide[i] = 0) then begin
- if first then begin
- writeln('Objects that you see here:');
- first := false;
- end;
- writeln(' ',obj_part(here.objs[i]));
- end;
- end;
- if first then
- writeln('There is nothing you see here that you can get.');
- end;
-
-
-
- { print the get success message for object number n }
-
- procedure p_getsucc(n: integer);
-
- begin
- { we assume getobj has already been done }
- if (obj.getsuccess = 0) or (obj.getsuccess = DEFAULT_LINE) then
- writeln('Taken.')
- else
- print_desc(obj.getsuccess);
- end;
-
-
- procedure do_meta_get(n: integer);
- var
- slot: integer;
-
- begin
- if obj_here(n) then begin
- if can_hold then begin
- slot := find_obj(n);
- if take_obj(n,slot) then begin
- hold_obj(n);
- log_event(myslot,E_GET,0,0,
- { >>> } myname + ' has picked up ' + obj_part(n) + '.');
- p_getsucc(n);
- end else
- writeln('Someone got to it before you did.');
- end else
- writeln('Your hands are full. You''ll have to drop something you''re carrying first.');
- end else if obj_hold(n) then
- writeln('You''re already holding that item.')
- else
- writeln('That item isn''t in an obvious place.');
- end;
-
-
- procedure do_get(s: string);
- var
- n: integer;
- ok: boolean;
-
- begin
- if s = '' then begin
- list_get;
- end else if parse_obj(n,s,TRUE) then begin
- getobj(n);
- freeobj;
- ok := true;
-
- if obj.sticky then begin
- ok := false;
- log_event(myslot,E_FAILGET,n,0);
- if (obj.getfail = 0) or (obj.getfail = DEFAULT_LINE) then
- writeln('You can''t take ',obj_part(n,FALSE),'.')
- else
- print_desc(obj.getfail);
- end else if obj.getobjreq > 0 then begin
- if not(obj_hold(obj.getobjreq)) then begin
- ok := false;
- log_event(myslot,E_FAILGET,n,0);
- if (obj.getfail = 0) or (obj.getfail = DEFAULT_LINE) then
- writeln('You''ll need something first to get the ',obj_part(n,FALSE),'.')
- else
- print_desc(obj.getfail);
- end;
- end;
-
- if ok then
- do_meta_get(n); { get the object }
-
- end else if lookup_detail(n,s) then begin
- writeln('That detail of this room is here for the enjoyment of all Monster players,');
- writeln('and may not be taken.');
- end else
- writeln('There is no object here by that name.');
- end;
-
-
- procedure do_drop(s: string);
- var
- slot,n: integer;
-
- begin
- if s = '' then begin
- writeln('To drop an object, type DROP <object name>.');
- writeln('To see what you are carrying, type INV (inventory).');
- end else if parse_obj(n,s) then begin
- if obj_hold(n) then begin
- getobj(n);
- freeobj;
- if obj.sticky then
- writeln('You can''t drop sticky objects.')
- else if can_drop then begin
- slot := find_hold(n);
- if place_obj(n) then begin
- drop_obj(slot);
- log_event(myslot,E_DROP,0,n,
- myname + ' has dropped '+obj_part(n) + '.');
-
- if mywield = n then begin
- mywield := 0;
- getroom;
- here.people[myslot].wielding := 0;
- putroom;
- end;
- if mywear = n then begin
- mywear := 0;
- getroom;
- here.people[myslot].wearing := 0;
- putroom;
- end;
- end else
- writeln('Someone took the spot where your were going to drop it.');
- end else
- writeln('It is too cluttered here. Find somewhere else to drop your things.');
- end else begin
- writeln('You''re not holding that item. To see what you''re holding, type INV.');
- end;
- end else
- writeln('You''re not holding that item. To see what you''re holding, type INVENTORY.');
- end;
-
-
- procedure do_inv(s: string);
- var
- first: boolean;
- i,n: integer;
- objnum: integer;
-
- begin
- gethere;
- if s = '' then begin
- noisehide(50);
- first := true;
- log_event(myslot,E_INVENT,0,0);
- for i := 1 to maxhold do begin
- objnum := here.people[myslot].holding[i];
- if objnum <> 0 then begin
- if first then begin
- writeln('You are holding:');
- first := false;
- end;
- writeln(' ',obj_part(objnum));
- end;
- end;
- if first then
- writeln('You are empty handed.');
- end else if parse_pers(n,s) then begin
- first := true;
- log_event(myslot,E_LOOKYOU,n,0);
- for i := 1 to maxhold do begin
- objnum := here.people[n].holding[i];
- if objnum <> 0 then begin
- if first then begin
- writeln(here.people[n].name,' is holding:');
- first := false;
- end;
- writeln(' ',objnam.idents[ objnum ]);
- end;
- end;
- if first then
- writeln(here.people[n].name,' is empty handed.');
- end else
- writeln('To see what someone else is carrying, type INV <personal name>.');
- end;
-
-
- { translate a personal name into a real userid on request }
-
- procedure do_whois(s: string);
- var
- n: integer;
-
- begin
- if lookup_pers(n,s) then begin
- getuser;
- freeuser;
- { getpers;
- freepers; ! Already done in lookup_pers ! }
-
- writeln(pers.idents[n],' is ',user.idents[n],'.');
- end else
- writeln('There is no one playing with that personal name.');
- end;
-
-
- procedure do_players(s: string);
- var
- i,j: integer;
- tmpasleep: indexrec;
- where_they_are: intrec;
-
- begin
- log_event(myslot,E_PLAYERS,0,0);
- getindex(I_ASLEEP); { Rec of bool; False if playing now }
- freeindex;
- tmpasleep := indx;
-
- getindex(I_PLAYER); { Rec of valid player log records }
- freeindex; { False if a valid player log }
-
- getuser; { Corresponding userids of players }
- freeuser;
-
- getpers; { Personal names of players }
- freepers;
-
- getdate; { date of last play }
- freedate;
-
- if privd then begin
- getint(N_LOCATION);
- freeint;
- where_they_are := anint;
-
- getnam;
- freenam;
- end;
-
- getint(N_SELF);
- freeint;
-
- writeln;
- writeln('Userid Personal Name Last Play');
- for i := 1 to maxplayers do begin
- if not(indx.free[i]) then begin
- write(user.idents[i]);
- for j := length(user.idents[i]) to 15 do
- write(' ');
- write(pers.idents[i]);
- for j := length(pers.idents[i]) to 21 do
- write(' ');
-
- if tmpasleep.free[i] then begin
- write(adate.idents[i]);
- if length(adate.idents[i]) < 19 then
- for j := length(adate.idents[i]) to 18 do
- write(' ');
- end else
- write(' -playing now- ');
-
- if (anint.int[i] <> 0) and (anint.int[i] <> DEFAULT_LINE) then
- write(' * ')
- else
- write(' ');
-
- if privd then begin
- write(nam.idents[ where_they_are.int[i] ]);
- end;
- writeln;
- end;
- end;
- writeln;
- end;
-
-
- procedure do_self(s: string);
- var
- n: integer;
-
- begin
- if length(s) = 0 then begin
- log_action(c_self,0);
- writeln('[ Editing your self description ]');
- if edit_desc(myself) then begin
- getroom;
- here.people[myslot].self := myself;
- putroom;
- getint(N_SELF);
- anint.int[mylog] := myself;
- putint;
- log_event(myslot,E_SELFDONE,0,0);
- end;
- end else if lookup_pers(n,s) then begin
- getint(N_SELF);
- freeint;
- if (anint.int[n] = 0) or (anint.int[n] = DEFAULT_LINE) then
- writeln('That person has not made a self-description.')
- else begin
- print_desc(anint.int[n]);
- log_event(myslot,E_VIEWSELF,0,0,pers.idents[n]);
- end;
- end else
- writeln('There is no person by that name.');
- end;
-
-
- procedure do_health(s: string);
-
- begin
- write('You ');
- case myhealth of
- 9: writeln('are in exceptional health.');
- 8: writeln('are in better than average condition.');
- 7: writeln('are in perfect health.');
- 6: writeln('feel a little bit dazed.');
- 5: writeln('have some minor cuts and abrasions.');
- 4: writeln('have some wounds, but are still fairly strong.');
- 3: writeln('are suffering from some serious wounds.');
- 2: writeln('are very badly wounded.');
- 1: writeln('have many serious wounds, and are near death.');
- 0: writeln('are dead.');
- otherwise writeln('don''t seem to be in any condition at all.');
- end;
- end;
-
-
- procedure crystal_look(chill_msg: integer);
- var
- numobj,numppl,numsee: integer;
- i: integer;
- yes: boolean;
-
- begin
- writeln;
- print_desc(here.primary);
- log_event(0,E_CHILL,chill_msg,0,'',here.locnum);
- numppl := find_numpeople;
- numsee := n_can_see + 1;
-
- if numppl > numsee then
- writeln('Someone is hiding here.')
- else if numppl = 0 then begin
- writeln('Strange, empty shadows swirl before your eyes.');
- end;
- if rnd100 > 50 then
- people_header('at this place.')
- else case numppl of
- 0: writeln('Vague empty forms drift through your view.');
- 1: writeln('You can make out a shadowy figure here.');
- 2: writeln('There are two dark figures here.');
- 3: writeln('You can see the silhouettes of three people.');
- otherwise
- writeln('Many dark figures can be seen here.');
- end;
-
- numobj := find_numobjs;
- if rnd100 > 50 then begin
- if rnd100 > 50 then
- show_objects
- else if numobj > 0 then
- writeln('Some objects are here.')
- else
- writeln('There are no objects here.');
- end else begin
- yes := false;
- for i := 1 to maxobjs do
- if here.objhide[i] <> 0 then
- yes := true;
- if yes then
- writeln('Something is hidden here.');
- end;
- writeln;
- end;
-
-
- procedure use_crystal(objnum: integer);
- var
- done: boolean;
- s: string;
- n: integer;
- done_msg,chill_msg: integer;
- tmp: string;
- i: integer;
-
- begin
- if obj_hold(objnum) then begin
- log_action(e_usecrystal,0);
- getobj(objnum);
- freeobj;
- done_msg := obj.d1;
- chill_msg := obj.d2;
-
- grab_line('',s);
- if lookup_room(n,s) then begin
- gethere(n);
- crystal_look(chill_msg);
- done := false;
- end else
- done := true;
-
- while not(done) do begin
- grab_line('',s);
- if lookup_dir(n,s) then begin
- if here.exits[n].toloc > 0 then begin
- gethere(here.exits[n].toloc);
- crystal_look(chill_msg);
- end;
- end else begin
- s := lowcase(s);
- tmp := bite(s);
- if tmp = 'poof' then begin
- if lookup_room(n,s) then begin
- gethere(n);
- crystal_look(chill_msg);
- end else
- done := true;
- end else if tmp = 'say' then begin
- i := (rnd100 mod 4) + 1;
- log_event(0,E_NOISE2,i,0,'',n);
- end else
- done := true;
- end;
- end;
-
- gethere;
- log_event(myslot,E_DONECRYSTALUSE,0,0);
- print_desc(done_msg);
- end else
- writeln('You must be holding it first.');
- end;
-
-
-
- procedure p_usefail(n: integer);
-
- begin
- { we assume getobj has already been done }
- if (obj.usefail = 0) or (obj.usefail = DEFAULT_LINE) then
- writeln('It doesn''t work for some reason.')
- else
- print_desc(obj.usefail);
- end;
-
-
- procedure p_usesucc(n: integer);
-
- begin
- { we assume getobj has already been done }
- if (obj.usesuccess = 0) or (obj.usesuccess = DEFAULT_LINE) then
- writeln('It seems to work, but nothing appears to happen.')
- else
- print_desc(obj.usesuccess);
- end;
-
-
- procedure do_use(s: string);
- var
- n: integer;
-
- begin
- if length(s) = 0 then
- writeln('To use an object, type USE <object name>')
- else if parse_obj(n,s) then begin
- getobj(n);
- freeobj;
-
- if (obj.useobjreq > 0) and not(obj_hold(obj.useobjreq)) then begin
- log_event(myslot,E_FAILUSE,n,0);
- p_usefail(n);
- end else if (obj.uselocreq > 0) and (location <> obj.uselocreq) then begin
- log_event(myslot,E_FAILUSE,n,0);
- p_usefail(n);
- end else begin
- p_usesucc(n);
- case obj.kind of
- O_BLAND:;
- O_CRYSTAL: use_crystal(n);
- otherwise ;
- end;
- end;
- end else
- writeln('There is no such object here.');
- end;
-
-
- procedure do_whisper(s: string);
- var
- n: integer;
-
- begin
- if length(s) = 0 then begin
- writeln('To whisper to someone, type WHISPER <personal name>.');
- end else if parse_pers(n,s) then begin
- if n = myslot then
- writeln('You can''t whisper to yourself.')
- else begin
- grab_line('>> ',s);
- if length(s) > 0 then begin
- nice_say(s);
- log_event(myslot,E_WHISPER,n,0,s);
- end else
- writeln('Nothing whispered.');
- end;
- end else
- writeln('No such person can be seen here.');
- end;
-
-
- procedure do_wield(s: string);
- var
- tmp: string;
- slot,n: integer;
-
- begin
- if length(s) = 0 then begin { no parms means unwield }
- if mywield = 0 then
- writeln('You are not wielding anything.')
- else begin
- getobj(mywield);
- freeobj;
- tmp := obj.oname;
- log_event(myslot,E_UNWIELD,0,0,tmp);
- writeln('You are no longer wielding the ',tmp,'.');
-
- mywield := 0;
- getroom;
- here.people[mylog].wielding := 0;
- putroom;
- end;
- end else if parse_obj(n,s) then begin
- if mywield <> 0 then begin
- writeln('You are already wielding ',obj_part(mywield),'.');
- end else begin
- getobj(n);
- freeobj;
- tmp := obj.oname;
- if obj.kind = O_WEAPON then begin
- if obj_hold(n) then begin
- mywield := n;
- getroom;
- here.people[myslot].wielding := n;
- putroom;
-
- log_event(myslot,E_WIELD,0,0,tmp);
- writeln('You are now wielding the ',tmp,'.');
- end else
- writeln('You must be holding it first.');
- end else
- writeln('That is not a weapon.');
- end;
- end else
- writeln('No such weapon can be seen here.');
- end;
-
-
- procedure do_wear(s: string);
- var
- tmp: string;
- slot,n: integer;
-
- begin
- if length(s) = 0 then begin { no parms means unwield }
- if mywear = 0 then
- writeln('You are not wearing anything.')
- else begin
- getobj(mywear);
- freeobj;
- tmp := obj.oname;
- log_event(myslot,E_UNWEAR,0,0,tmp);
- writeln('You are no longer wearing the ',tmp,'.');
-
- mywear := 0;
- getroom;
- here.people[mylog].wearing := 0;
- putroom;
- end;
- end else if parse_obj(n,s) then begin
- getobj(n);
- freeobj;
- tmp := obj.oname;
- if (obj.kind = O_ARMOR) or (obj.kind = O_CLOAK) then begin
- if obj_hold(n) then begin
- mywear := n;
- getroom;
- here.people[mylog].wearing := n;
- putroom;
-
- log_event(myslot,E_WEAR,0,0,tmp);
- writeln('You are now wearing the ',tmp,'.');
- end else
- writeln('You must be holding it first.');
- end else
- writeln('That cannot be worn.');
- end else
- writeln('No such thing can be seen here.');
- end;
-
-
- procedure do_brief;
-
- begin
- brief := not(brief);
- if brief then
- writeln('Brief descriptions.')
- else
- writeln('Verbose descriptions.');
- end;
-
-
- function p_door_key(n: integer): string;
-
- begin
- if n = 0 then
- p_door_key := '<none>'
- else
- p_door_key := objnam.idents[n];
- end;
-
-
-
- procedure anal_exit(dir: integer);
-
- begin
- if (here.exits[dir].toloc = 0) and (here.exits[dir].kind <> 5) then
- { no exit here, don't print anything }
- else with here.exits[dir] do begin
- write(direct[dir]);
- if length(alias) > 0 then begin
- write('(',alias);
- if reqalias then
- write(' required): ')
- else
- write('): ');
- end else
- write(': ');
-
- if (toloc = 0) and (kind = 5) then
- write('accept, no exit yet')
- else if toloc > 0 then begin
- write('to ',nam.idents[toloc],', ');
- case kind of
- 0: write('no exit');
- 1: write('open passage');
- 2: write('door, key=',p_door_key(objreq));
- 3: write('~door, ~key=',p_door_key(objreq));
- 4: write('exit open randomly');
- 5: write('potential exit');
- 6: write('xdoor, key=',p_door_key(objreq));
- 7: begin
- write('timed exit, now ');
- if cycle_open then
- write('open')
- else
- write('closed');
- end;
- end;
- if hidden <> 0 then
- write(', hidden');
- if reqverb then
- write(', reqverb');
- if not(autolook) then
- write(', autolook off');
- if here.trapto = dir then
- write(', trapdoor (',here.trapchance:1,'%)');
- end;
- writeln;
- end;
- end;
-
-
- procedure do_s_exits;
- var
- i: integer;
- accept,one: boolean; { accept is true if the particular exit is
- an "accept" (other players may link there)
- one means at least one exit was shown }
-
- begin
- one := false;
- gethere;
-
- for i := 1 to maxexit do begin
- if (here.exits[i].toloc = 0) and (here.exits[i].kind = 5) then
- accept := true
- else
- accept := false;
-
- if (can_alter(i)) or (accept) then begin
- if not(one) then begin { first time we do this then }
- getnam; { read room name list in }
- freenam;
- getobjnam;
- freeobjnam;
- end;
- one := true;
- anal_exit(i);
- end;
- end;
-
- if not(one) then
- writeln('There are no exits here which you may inspect.');
- end;
-
-
- procedure do_s_object(s: string);
- var
- n: integer;
- x: objectrec;
-
- begin
- if length(s) = 0 then begin
- grab_line('Object? ',s);
- end;
-
- if lookup_obj(n,s) then begin
- if obj_owner(n,TRUE) then begin
- write(obj_part(n),': ');
- write(objown.idents[n],' is owner');
- x := obj;
-
- if x.sticky then
- write(', sticky');
- if x.getobjreq > 0 then
- write(', ',obj_part(x.getobjreq),' required to get');
- if x.useobjreq > 0 then
- write(', ',obj_part(x.useobjreq),' required to use');
- if x.uselocreq > 0 then begin
- getnam;
- freenam;
- write(', used only in ',nam.idents[x.uselocreq]);
- end;
- if x.usealias <> '' then begin
- write(', use="',x.usealias,'"');
- if x.reqalias then
- write(' (required)');
- end;
-
- writeln;
- end else
- writeln('You are not allowed to see the internals of that object.');
- end else
- writeln('There is no such object.');
- end;
-
-
- procedure do_s_details;
- var
- i: integer;
- one: boolean;
-
- begin
- gethere;
- one := false;
- for i := 1 to maxdetail do
- if (here.detail[i] <> '') and (here.detaildesc[i] <> 0) then begin
- if not(one) then begin
- one := true;
- writeln('Details here that you may inspect:');
- end;
- writeln(' ',here.detail[i]);
- end;
- if not(one) then
- writeln('There are no details of this room that you can inspect.');
- end;
-
- procedure do_s_help;
-
- begin
- writeln;
- writeln('Exits Lists exits you can inspect here');
- writeln('Object Show internals of an object');
- writeln('Details Show details you can look at in this room');
- writeln;
- end;
-
-
- procedure s_show(n: integer;s: string);
-
- begin
- case n of
- s_exits: do_s_exits;
- s_object: do_s_object(s);
- s_quest: do_s_help;
- s_details: do_s_details;
- end;
- end;
-
-
- procedure do_y_altmsg;
- var
- newdsc: integer;
-
- begin
- if is_owner then begin
- gethere;
- newdsc := here.xmsg2;
- writeln('[ Editing the alternate mystery message for this room ]');
- if edit_desc(newdsc) then begin
- getroom;
- here.xmsg2 := newdsc;
- putroom;
- end;
- end;
- end;
-
-
- procedure do_y_help;
-
- begin
- writeln;
- writeln('Altmsg Set the alternate mystery message block');
- writeln;
- end;
-
-
- procedure do_group1;
- var
- grpnam: string;
- loc: integer;
- tmp: string;
-
- begin
- if is_owner then begin
- gethere;
- if here.grploc1 = 0 then
- writeln('No primary group location set')
- else begin
- getnam;
- freenam;
- writeln('The primary group location is ',nam.idents[here.grploc1],'.');
- writeln('Descriptor string: [',here.grpnam1,']');
- end;
- writeln;
- writeln('Type * to turn off the primary group location');
- grab_line('Room name of primary group? ',grpnam);
- if length(grpnam) = 0 then
- writeln('No changes.')
- else if grpnam = '*' then begin
- getroom;
- here.grploc1 := 0;
- putroom;
- end else if lookup_room(loc,grpnam) then begin
- writeln('Enter the descriptive string. It will be placed after player names.');
- writeln('Example: Monster Manager is [descriptive string, instead of "here."]');
- writeln;
- grab_line('Enter string? ',tmp);
- if length(tmp) > shortlen then begin
- writeln('Your string was truncated to ',shortlen:1,' characters.');
- tmp := substr(tmp,1,shortlen);
- end;
- getroom;
- here.grploc1 := loc;
- here.grpnam1 := tmp;
- putroom;
- end else
- writeln('No such room.');
- end;
- end;
-
-
-
- procedure do_group2;
- var
- grpnam: string;
- loc: integer;
- tmp: string;
-
- begin
- if is_owner then begin
- gethere;
- if here.grploc2 = 0 then
- writeln('No secondary group location set')
- else begin
- getnam;
- freenam;
- writeln('The secondary group location is ',nam.idents[here.grploc1],'.');
- writeln('Descriptor string: [',here.grpnam1,']');
- end;
- writeln;
- writeln('Type * to turn off the secondary group location');
- grab_line('Room name of secondary group? ',grpnam);
- if length(grpnam) = 0 then
- writeln('No changes.')
- else if grpnam = '*' then begin
- getroom;
- here.grploc2 := 0;
- putroom;
- end else if lookup_room(loc,grpnam) then begin
- writeln('Enter the descriptive string. It will be placed after player names.');
- writeln('Example: Monster Manager is [descriptive string, instead of "here."]');
- writeln;
- grab_line('Enter string? ',tmp);
- if length(tmp) > shortlen then begin
- writeln('Your string was truncated to ',shortlen:1,' characters.');
- tmp := substr(tmp,1,shortlen);
- end;
- getroom;
- here.grploc2 := loc;
- here.grpnam2 := tmp;
- putroom;
- end else
- writeln('No such room.');
- end;
- end;
-
-
- procedure s_set(n: integer;s: string);
-
- begin
- case n of
- y_quest: do_y_help;
- y_altmsg: do_y_altmsg;
- y_group1: do_group1;
- y_group2: do_group2;
- end;
- end;
-
-
- procedure do_show(s: string);
- var
- n: integer;
- cmd: string;
-
- begin
- cmd := bite(s);
- if length(cmd) = 0 then
- grab_line('Show what attribute? (type ? for a list) ',cmd);
-
- if length(cmd) = 0 then
- else if lookup_show(n,cmd) then
- s_show(n,s)
- else
- writeln('Invalid show option, type SHOW ? for a list.');
- end;
-
-
- procedure do_set(s: string);
- var
- n: integer;
- cmd: string;
-
- begin
- cmd := bite(s);
- if length(cmd) = 0 then
- grab_line('Set what attribute? (type ? for a list) ',cmd);
-
- if length(cmd) = 0 then
- else if lookup_set(n,cmd) then
- s_set(n,s)
- else
- writeln('Invalid set option, type SET ? for a list.');
- end;
-
-
- procedure parser;
- var
- s: string;
- cmd: string;
- n: integer;
- dummybool: boolean;
-
- begin
- repeat
- grab_line('> ',s);
- s := slead(s);
- until length(s) > 0;
-
- if s = '.' then
- s := oldcmd
- else
- oldcmd := s;
-
- if (s[1]='''') and (length(s) > 1) then
- do_say(substr(s,2,length(s)-1))
- else begin
- cmd := bite(s);
- case lookup_cmd(cmd) of
- { try exit alias } error:begin
- if (lookup_alias(n,cmd)) or
- (lookup_dir(n,cmd)) then begin
- do_go(cmd);
- end else
- writeln('Bad command, type ? for a list.');
- end;
-
- setnam: do_setname(s);
- help,quest: show_help;
- quit: done := true;
- c_l,look: do_look(s);
- go: do_go(s,FALSE); { FALSE = dir not a verb }
- form: do_form(s);
- link: do_link(s);
- unlink: do_unlink(s);
- poof: do_poof(s);
- desc: do_describe(s);
- say: do_say(s);
- c_rooms: do_rooms(s);
- c_claim: do_claim(s);
- c_disown: do_disown(s);
- c_public: do_public(s);
- c_accept: do_accept(s);
- c_refuse: do_refuse(s);
- c_zap: do_zap(s);
-
- c_north,c_n,
- c_south,c_s,
- c_east,c_e,
- c_west,c_w,
- c_up,c_u,
- c_down,c_d: do_go(cmd);
-
- c_who: do_who;
- c_custom: do_custom(s);
- c_search: do_search(s);
- c_system: do_system(s);
- c_hide: do_hide(s);
- c_unhide: do_unhide(s);
- c_punch: do_punch(s);
- c_ping: do_ping(s);
- c_create: do_makeobj(s);
- c_get: do_get(s);
- c_drop: do_drop(s);
- c_i,c_inv: do_inv(s);
- c_whois: do_whois(s);
- c_players: do_players(s);
- c_health: do_health(s);
- c_duplicate: do_duplicate(s);
- c_version: do_version(s);
- c_objects: do_objects;
- c_self: do_self(s);
- c_use: do_use(s);
- c_whisper: do_whisper(s);
- c_wield: do_wield(s);
- c_brief: do_brief;
- c_wear: do_wear(s);
- c_destroy: do_destroy(s);
- c_relink: do_relink(s);
- c_unmake: do_unmake(s);
- c_show: do_show(s);
- c_set: do_set(s);
-
- dbg: begin
- debug := not(debug);
- if debug then
- writeln('Debugging is on.')
- else
- writeln('Debugging is off.');
- end;
- otherwise begin
- writeln('%Parser error, bad return from lookup');
- end;
- end;
- clear_command;
- end;
- end;
-
-
-
- procedure init;
- var
- i: integer;
-
- begin
- rndcycle := 0;
- location := 1; { Great Hall }
-
- mywield := 0; { not initially wearing or weilding any weapon }
- mywear := 0;
- myhealth := 7; { how healthy they are to start }
- healthcycle := 0; { pretty much meaningless at the start }
-
- userid := lowcase(get_userid);
- if (userid = MM_userid) then begin
- myname := 'Monster Manager';
- privd := true;
- end else if (userid = MVM_userid) then begin
- privd := true;
- myname := 'Vice Manager';
- end else if (userid = FAUST_userid) then begin
- privd := true;
- end else begin
- myname := lowcase(userid);
- myname[1] := chr( ord('A') + (ord(myname[1]) - ord('a')) );
- privd := false;
- end;
-
- numcmds:= 66;
-
- show[s_exits] := 'exits';
- show[s_object] := 'object';
- show[s_quest] := '?';
- show[s_details] := 'details';
- numshow := 4;
-
- setkey[y_quest] := '?';
- setkey[y_altmsg] := 'altmsg';
- setkey[y_group1] := 'group1';
- setkey[y_group2] := 'group2';
- numset := 4;
-
- numspells := 0;
-
- open(roomfile,root+'ROOMS.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(namfile,root+'NAMS.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(eventfile,root+'EVENTS.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(descfile,root+'DESC.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(indexfile,root+'INDEX.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(linefile,root+'LINE.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(intfile,root+'INTFILE.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(objfile,root+'OBJECTS.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- open(spellfile,root+'SPELLS.MON',access_method := direct,
- sharing := readwrite,
- history := unknown);
- end;
-
-
- procedure prestart;
- var
- s: string;
-
- begin
- write('Welcome to Monster! Hit return to start: ');
- readln(s);
- writeln;
- writeln;
- if length(s) > 0 then
- special(lowcase(s));
- end;
-
-
- procedure welcome_back(var mylog: integer);
- var
- tmp: string;
- sdate,stime: shortstring;
-
- begin
- getdate;
- freedate;
-
- write('Welcome back, ',myname,'.');
- if length(myname) > 18 then
- writeln;
-
- write(' Your last play was on');
-
- if length(adate.idents[mylog]) < 11 then begin
- writeln(' ???');
- end else begin
- sdate := substr(adate.idents[mylog],1,11); { extract the date }
- if length(adate.idents[mylog]) = 19 then
- stime := substr(adate.idents[mylog],13,7)
- else
- stime := '???';
-
- if sdate[1] = ' ' then
- tmp := sdate
- else
- tmp := ' ' + sdate;
-
- if stime[1] = ' ' then
- tmp := tmp + ' at' + stime
- else
- tmp := tmp + ' at ' + stime;
- writeln(tmp,'.');
- end;
- writeln;
- end;
-
-
- function loc_ping:boolean;
- var
- i: integer;
- found: boolean;
-
- begin
- inmem := false;
- gethere;
-
- i := 1;
- found := false;
-
- { first get the slot that the supposed "zombie" is in }
- while (not found) and (i <= maxpeople) do begin
- if here.people[i].name = myname then
- found := true
- else
- i := i + 1;
- end;
-
- myslot := 0; { setup for ping_player }
-
- if found then begin
- setevent;
- loc_ping := ping_player(i,TRUE); { TRUE = silent operation }
- end else
- loc_ping := true;
- { well, if we can't find them, let's assume
- that they're not in any room records, so they're
- ok . . . Let's hope... }
- end;
-
-
-
- { attempt to fix the player using loc_ping if the database incorrectly
- shows someone playing who isn' playing }
-
- function fix_player:boolean;
- var
- ok: boolean;
-
- begin
- writeln('There may have been some trouble the last time you played.');
- writeln('Trying to fix it . . .');
- if loc_ping then begin
- writeln('All should be fixed now.');
- writeln;
- fix_player := true;
- end else begin
- writeln('Either someone else is playing Monster on your account, or something is');
- writeln('very wrong with the database.');
- writeln;
- fix_player := false;
- end;
- end;
-
-
- function revive_player(var mylog: integer): boolean;
- var
- ok: boolean;
- i,n: integer;
-
- begin
- if exact_user(mylog,userid) then begin { player has played before }
- getint(N_LOCATION);
- freeint;
- location := anint.int[mylog]; { Retrieve their old loc }
-
- getpers;
- freepers;
- myname := pers.idents[mylog]; { Retrieve old personal name }
-
- getint(N_EXPERIENCE);
- freeint;
- myexperience := anint.int[mylog];
-
- getint(N_SELF);
- freeint;
- myself := anint.int[mylog];
-
- getindex(I_ASLEEP);
- freeindex;
-
- if indx.free[mylog] then begin
- { if player is asleep, all is well }
- ok := true;
- end else begin
- { otherwise, there is one of two possibilities:
- 1) someone on the same account is
- playing Monster
- 2) his last play terminated abnormally
- }
- ok := fix_player;
- end;
-
- if ok then
- welcome_back(mylog);
-
- end else begin { must allocate a log block for the player }
- if alloc_log(mylog) then begin
-
- writeln('Welcome to Monster, ',myname,'!');
- writeln('You will start in the Great Hall.');
- writeln;
-
- { Store their userid }
- getuser;
- user.idents[mylog] := lowcase(userid);
- putuser;
-
- { Set their initial location }
- getint(N_LOCATION);
- anint.int[mylog] := 1; { Start out in Great Hall }
- putint;
- location := 1;
-
- getint(N_EXPERIENCE);
- anint.int[mylog] := 0;
- putint;
- myexperience := 0;
-
- getint(N_SELF);
- anint.int[mylog] := 0;
- putint;
- myself := 0;
-
- { initialize the record containing the
- level of each spell they have to start;
- all start at zero; since the spellfile is
- directly parallel with mylog, we can hack
- init it here without dealing with SYSTEM }
-
- locate(spellfile,mylog);
- for i := 1 to maxspells do
- spellfile^.level[i] := 0;
- spellfile^.recnum := mylog;
- put(spellfile);
-
- ok := true;
- end else
- ok := false;
- end;
-
- if ok then begin { Successful, MYLOG is my log slot }
-
- { Wake up the player }
- getindex(I_ASLEEP);
- indx.free[mylog] := false; { I'm NOT asleep now }
- putindex;
-
- { Set the "last date of play" }
- getdate;
- adate.idents[mylog] := sysdate + ' ' + systime;
- putdate;
- end else
- writeln('There is no place for you in Monster. Contact the Monster Manager.');
- revive_player := ok;
- end;
-
-
- function enter_universe:boolean;
- var
- orignam: string;
- dummy,i: integer;
- ok: boolean;
-
- begin
-
-
- { take MYNAME given to us by init or revive_player and make
- sure it's unique. If it isn't tack _1, _2, etc onto it
- until it is. Code must come before alloc_log, or there
- will be an invalid pers record in there cause we aren't in yet
- }
- orignam := myname;
- i := 0;
- repeat { tack _n onto pers name until a unique one is found }
- ok := true;
-
- {*** Should this use exact_pers instead? Is this a copy of exact_pers code? }
-
- if lookup_pers(dummy,myname) then
- if lowcase(pers.idents[dummy]) = lowcase(myname) then begin
- ok := false;
- i := i + 1;
- writev(myname,orignam,'_',i:1);
- end;
- until ok;
-
-
-
- if revive_player(mylog) then begin
- if put_token(location,myslot) then begin
- getpers;
- pers.idents[mylog] := myname;
- putpers;
-
- enter_universe := true;
- log_begin(location);
- setevent;
- do_look;
- end else begin
- writeln('put_token failed.');
- enter_universe := false;
- end;
- end else begin
- writeln('revive_player failed.');
- enter_universe := false;
- end;
- end;
-
- procedure leave_universe;
- var
- diddrop: boolean;
-
- begin
- diddrop := drop_everything;
- take_token(myslot,location);
- log_quit(location,diddrop);
- do_endplay(mylog);
-
- writeln('You vanish in a brilliant burst of multicolored light.');
- if diddrop then
- writeln('All of your belongings drop to the ground.');
- end;
-
-
- begin
- done := false;
- setup_guts;
- init;
- prestart;
- if not(done) then begin
- if enter_universe then begin
- repeat
- parser;
- until done;
- leave_universe;
- end else
- writeln('You attempt to enter the Monster universe, but a strange force repels you.');
- end;
- finish_guts;
- end.
-
-
- { Notes to other who may inherit this program:
-
- Change all occurances in this file of dolpher to the account which
- you will use for maintenance of this program. That account will
- have special administrative powers.
-
- This program uses several data files. These files are in a directory
- specified by the variable root in procedure init. In my implementation,
- I have a default ACL on the directory allowing everyone READ and WRITE
- access to the files created in that directory. Whoever plays the game
- must be able to write to these data files.
-
-
- Written by Rich Skrenta, 1988.
-
-
-
-
- Brief program organization overview:
- ------------------------------------
-
- Monster's Shared Files:
-
- Monster uses several shared files for communication.
- Each shared file is accessed within Monster by a group of 3 procedures of the
- form: getX(), freeX and putX.
-
- getX takes an integer and attempts to get and lock that record from the
- appropriate data file. If it encounters a "collision", it waits a short
- random amount of time and tries again. After maxerr collisions it prints
- a deadlock warning message.
-
- If data is to be read but not changed, a freeX should immediately follow
- the getX so that other Monster processes can access the record. If the
- record is to be written then a putX must eventually follow the getX.
-
-
- Monster's Record Allocation:
-
- Monster dynamically allocates some resources such as description blocks and
- lines and player log entries. The allocation is from a bitmap. I chose a
- bitmap over a linked list to make the multiuser access to the database
- more stable. A particular resource (such as log entries) will have a
- particular bitmap in the file INDEXFILE. A getindex(I_LOG) will retrieve
- the bitmap for it.
-
- Actually allocation and deallocation is done through the group of functions
- alloc_X and delete_X. If alloc_X returns true, the allocation was successful,
- and the integer parameter is the number of the block allocated.
-
- The top available record in each group is stored in indexrec. To increase
- the top, the new records must be initially written so that garbage data is
- not in them and the getX routines can locate them. This can be done with
- the addX(n) group of routines, which add capacity to resources.
-
-
-
- Parsing in Monster:
-
- The main parser(s) use a first-unique-characters method to lookup command
- keywords and parameters. The format of these functions is lookup_x(n,s).
- If it returns true, it successfully found an unambiguous match to string s.
- The integer index will be in n.
-
- If an unambiguating match is needed (for example, if someone makes a new room,
- the match to see if the name exists shouldn't disambiguate), the group of
- routines exact_X(n,s) are called. They function similarly to lookup_x(n,s).
-
- The customization subsystems and the editor use very primitive parsers
- which only use first character match and integer arguments.
-
-
-
- Asynchronous events in Monster:
-
- When someone comes into a room, the other players in that room need
- to be notified, even if they might be typing a command on their terminal.
-
- This is done in a two part process (producer/consumer problem):
-
- When an event takes place, the player's Monster that caused the event
- makes a call to log_event. Parameters include the slot of the sender (which
- person in the room caused the event), the actual event that occurred
- (E_something) and parameters. Log_event works by sticking the event
- into a circular buffer associated with the room (room may be specified on
- log_event).
-
- Note: there is not an event record for every room; instead, the event
- record used is ROOM # mod ACTUAL NUMBER of EVENT RECORDS
-
- The other half of the process occurrs when a player's Monster calls
- grab_line to get some input. Grab line looks for keystrokes, and if
- there are none, it calls checkevent and then sleeps for a short time
- (.1 - .2 seconds). Checkevent loads the event record associated with this
- room and compare's the player's buffer pointer with the record's buffer
- pointer. If they are different, checkevent bites off events and sends them
- to handle_event until there are no more events to be processed. Checkevent
- ignores events logged by it's own player.
-
-
- }
-